数论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 ;
}