/* hdu3037 http://acm.hdu.edu.cn/showproblem.php?pid=3037 lucas 模板题 */ #include <cstdio> #include <cmath> const long long Nmax=100005; long long p; long long ex_gcd(long long a,long long b,long long &x,long long &y)//solve x,y in a*x+b*y=ex_gcd(a,b,x,y)=gcd(a,b); { if(b==0) { x=1LL; y=0LL; return a; } long long ans=ex_gcd(b,a%b,x,y); long long tmp=x; x=y; y=tmp-a/b*y; return ans; //x = x0 + (b/gcd)*t //y = y0 – (a/gcd)*t } long long get(long long a,long long m,long long c)//get x in a*x=c(mod m) { //we can solve x,y in a*x+b*y=c <=> c%gcd(a,b)==0 long long x,y; long long gcd=ex_gcd(a,m,x,y); if(c%gcd!=0) return -1;//error x*=c/gcd; if(m<0) m=-m; long long ans=x%m; while(ans<0) ans+=m; return ans; } // long long Cm(long long n,long long m,long long p)//C(n,m)=n!/(m!(n-m)!); // { // long long ans=1LL; // ans=fac(n)%p; // ans=(ans* (get(fac(m)*fac(n-m),p,1)%p) )%p; // return ans; // } long long Cm(long long n,long long m,long long p) { long long a=1,b=1; if(n<m) return 0LL; while(m>0) { a=(a*n)%p; b=(b*m)%p; n--; m--; } return a*get(b,p,1)%p; } //Lucas C(n*p+r,m*p+t)=C(r,t)*Lucas(n,m); long long lucas(long long n,long long m,long long p) //求C(n,m)%p p最大为10^5。a,b可以很大! { if(m==0) return 1; else return ( (Cm(n%p,m%p,p) %p ) * ( lucas(n/p,m/p,p) %p ) )%p; } int main() { // freopen("HDU3037.in","r",stdin); long long t; long long n,m; scanf("%d",&t); while(t--) { scanf("%lld%lld%lld",&n,&m,&p); printf("%lld\n",lucas(n+m,m,p)); } return 0; }
原文:http://www.cnblogs.com/BBBob/p/6522921.html