求(P是质数)[C_n^m\% p]
这个就是卢卡斯定理!!
它的精华就是[C(n,m,p) equiv C(n/p,m/p,p)*C(n\% p,m\% p,p)(\% p)]
然后呢就是一个开心的递归处理,
如果$n < p$就就算一下,逆元阶乘都很easy
上代码!
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 typedef long long lt; 5 lt n,m,p,T; 6 lt inv[100010],fac[100010]; 7 lt lucas(lt n,lt m,lt p) 8 { 9 if(n<m)return 0; 10 else if(n<p)return fac[n]*inv[m]*inv[n-m]%p; 11 else return lucas(n/p,m/p,p)*lucas(n%p,m%p,p)%p; 12 } 13 int main() 14 { 15 //freopen("testdata.in","r",stdin); 16 scanf("%lld",&T); 17 while(T--) 18 { 19 scanf("%lld%lld%lld",&n,&m,&p);n=n+m; 20 fac[0]=fac[1]=inv[1]=inv[0]=1; 21 for(int i=2;i<=n;i++)fac[i]=fac[i-1]*i%p; 22 for(int i=2;i<=p;i++)inv[i]=(p-p/i)*inv[p%i]%p; 23 for(int i=2;i<=p;i++)inv[i]=inv[i-1]*inv[i]%p; 24 printf("%lld ",lucas(n,m,p)); 25 } 26 return 0; 27 }