西电校赛网络赛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

 

posted @ 2015-05-06 09:30  __560  阅读(286)  评论(0编辑  收藏  举报