Lucas 定理

View Code
/*==================================================*\
| 求解 C(n,m)%p  保证p为素数n很大10^9 m很小10^5
\*==================================================*/
typedef __int64 int64;
int64 N,M, mod;
int64 p[MM];

void get_data() {
    int i,j,k;
    scanf("%I64d%I64d%I64d",&N,&M,&mod);
}
int64 exp_mod(int64 a,int64 b,int64 p) {
    int64 res=1;
    while(b) {
        if(b&1) {
            res=(res*a)%p;
        }
        b>>=1;
        a=(a*a)%p;
    }
    return res;
}
int64 com(int64 n,int64 m,int64 p) {
    int64 a=1,b,i;
    if(n<m) return 0;
    for(i=1;i<=m;i++) {
        a=(a*(n-i+1))%p;
        b=exp_mod(i,p-2,p);
        a=(a*b)%p;
    }
    return a;
}

int64 Lucas(int64 n,int64 m,int64 p) {
    int64 res=1;
    if(n<m) return 0;
    while(n && m) {
        res=(res*com(n%p,m%p,p))%p;
        n/=p, m/=p;
    }
    return res;
}

//100 100 2
void solve() {
    int i,j,k;
    printf("%I64d\n",Lucas(N,M,mod));
}
int main() {
    int ca; scanf("%d",&ca);
    while(ca--) get_data(),solve();
    return 0;
}

 

posted @ 2013-04-24 10:59  zhang1107  阅读(158)  评论(0编辑  收藏  举报