题目:http://acm.hdu.edu.cn/showproblem.php?pid=3037
卢卡斯定理模板——大组合数取模
#include<iostream> #include<cstdio> using namespace std; long long t,n,m,p,s; long long mi(long long a,long long k) { long long s=1; while(k) { if(k&1)s=s*a%p; k>>=1; a=a*a%p; } return s; } long long getc(long long n,long long m) { if(n<m)return 0; long long s1=1; long long s2=1; if(n-m<m)m=n-m; for(long long i=1,j=n;i<=m;j--,i++) { s1=s1*j%p; s2=s2*i%p; } return s1*mi(s2,p-2)%p; } long long lucas(long long n,long long m) { if(!m)return 1; return lucas(n/p,m/p)*getc(n%p,m%p)%p; } int main() { scanf("%lld",&t); while(t--) { scanf("%lld%lld%lld",&n,&m,&p); printf("%lld ",lucas(n+m,n)); } return 0; }
或
#include<iostream> #include<cstdio> using namespace std; long long t,n,m,p,s,js[100005]={1}; long long mi(long long a,long long k) { long long s=1; while(k>0) { if(k&1)s=s*a%p; k>>=1; a=a*a%p; } return s; } long long getc(long long n,long long m) { if(n<m)return 0; if(n-m<m)m=n-m; return js[n]*mi(js[m],p-2)%p*mi(js[n-m],p-2)%p; } long long lucas(long long n,long long m) { if(!m)return 1; return lucas(n/p,m/p)*getc(n%p,m%p)%p; } int main() { scanf("%lld",&t); while(t--) { scanf("%lld%lld%lld",&n,&m,&p); for(int i=1;i<=p;i++) js[i]=js[i-1]*i%p; printf("%lld ",lucas(n+m,n)); } return 0; }