卢卡斯定理
卢卡斯定理是用来求组合数取模的一种log级别的算法。
Lucas(n,m,p)=c(n%p,m%p)*Lucas(n/p,m/p,p)
至于组合数怎么求可以参考逆元博客。
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #define ll long long #define il inline #define db double using namespace std; int k,n,m,p; ll a[100045],b[100045]; ll luca(int x,int y) { if(x<y) return 0; else if(x<p) return b[x]*a[y]*a[x-y]%p; else return luca(x/p,y/p)*luca(x%p,y%p)%p; } int main() { scanf("%d",&k); for(int i=1;i<=k;i++) { scanf("%d%d%d",&n,&m,&p); a[0]=a[1]=b[0]=b[1]=1; for(int i=2;i<=n+m;i++) a[i]=(p-p/i)*a[p%i]%p,b[i]=b[i-1]*i%p; for(int i=2;i<=n+m;i++) a[i]=a[i-1]*a[i]%p; printf("%lld\n",luca(n+m,m)); } return 0; }
PEACE