Lucas定理

数论Lucas定理是用来求 c(n,m) mod p的值,p是素数(从n取m组合,模上p)。
描述为:
Lucas(n,m,p)= c(n%p,m%p)* Lucas(n/p,m/p,p)
Lucas(x,0,p)=1;
c(a,b)=a! * (b!*(a-b)!)^(p-2) mod p
也= (a!/(a-b)!) * (b!)^(p-2)) mod p
这里,其实就是直接求 (a!/(a-b)!) / (b!) mod p
由于 (a/b) mod p = a * b^(p-2) mod p     (费马小定理而来)
http://acm.fzu.edu.cn/problem.php?pid=2020
求C(n,m) mod p的结果

typedef long long LL  ;

LL   POW(LL x , LL y , LL mod){
     LL ans = 1 ;
     for( ; y ; y>>=1){
        if(y&1){
           ans *= x ;
           ans %= mod ;
        }
        x *= x ;
        x %= mod ;
     }
     return ans  ;
}

LL  C(LL n , LL m , LL mod){
    if(n < m)
         return 0 ;
    LL ans = 1 ;
    for(LL i = 1 ; i <= m ; i++){
         ans *= (n-i+1) ;
         ans %= mod ;
         ans *= POW(i , mod-2 , mod) ;
         ans %= mod ;
    }
    return ans ;
}

LL lucas(LL  n  , LL m , LL mod){
   LL ans = 1 ;
   while(n && m){
        ans *= C(n%mod , m%mod , mod) ;
        if(ans == 0)
            return ans ;
        n /= mod  ;
        m /= mod  ;
        ans %= mod ;
   }
   return ans ;
}

int  main(){
     int T ;
     LL  n , m , p ;
     scanf("%d" ,&T) ;
     while(T--){
          scanf("%I64d%I64d%I64d" ,&n ,&m ,&p) ;
          printf("%I64d\n" ,lucas(n , m ,p)) ;
     }
     return  0 ;
}


你可能感兴趣的:(Lucas定理)