西电校赛网络赛J题 lucas定理计算组合数

西电校赛网络赛J题  lucas定理计算组合数

问题 J: 找规律II

时间限制: 1 Sec  内存限制: 128 MB 提交: 96  解决: 16 [提交][状态][讨论版]

题目描述

现有数阵如下:
 1    2  3   4     5    6
       1   3   6  10  15
            1   4  10   20
                  1   5   15
                        1    6
                              1
求这个数阵的第n行m列是多少(行列标号从1开始)
结果对10007取模

 

输入

多组数据,每组数据一行,包含两个整数n,m(1<=n<=m<=10^18)

 

输出

每组数据输出一行,为数阵中第n行m列对10007取模后的值。

 

样例输入

1 1

1 2

1 3

样例输出

1

2

3
#include<iostream>

#include<cstdio>

#include<cstdlib>

#include<cstring>

#include<algorithm>



using namespace std;



const int maxn=1000100;

const int INF=(1<<29);

const int p=10007;



typedef unsigned long long ll;



ll n,m;



ll qpow(ll n,ll k)

{

    ll res=1;

    while(k){

        if(k&1) res=(res%p)*(n%p)%p;

        n=(n%p)*(n%p)%p;

        k>>=1;

    }

    return res;

}



ll C(ll n,ll k)

{

    if(n<k) return 0;

    ll res=1;

    for(int i=1;i<=k;i++){

        ll a=(n-k+i)%p;

        ll b=i%p;

        res=res*(a*qpow(b,p-2)%p)%p;

    }

    return res%p;

}



ll lucas(ll n,ll k)

{

    if(k==0) return 1;

    return (C(n%p,k%p)%p)*(lucas(n/p,k/p)%p)%p;

}



int main()

{

    while(cin>>n>>m){

        cout<<lucas(m,n)<<endl;

    }

    return 0;

}
View Code

 

你可能感兴趣的:(cas)