當$p$爲素數時ios
$$C_n^m\equiv C_{n/p}^{m/p}*C_{n\%p}^{m\%p}(mod\ p)$$git
設$n=s*p+q,m\equiv t*p+r(q,r<=p)$ui
咱們要證$C_{s*p+q}^{t*p+r}\equiv C_s^t*C_q^r$spa
首先得有個前置知識,費馬小定理$x^p\equiv x(mod\ p)$code
那麼$(x+1)^p\equiv x+1(mod\ p)$blog
且$x^p+1\equiv x+1(mod\ p)$get
因此$(x+1)^p\equiv x^p+1$it
而後$(x+1)^n\equiv (x+1)^{s*p+q}$io
$\equiv ((x+1)^p)^s*(x+1)^q$class
$\equiv (x^p+1)^s*(x+1)^q$
而後用二項式定理展開
$\equiv \sum _{i=0}^s C_s^i*x^{i*p}*\sum_{j=0}^qC_q^j*x^j$
總之就是$(x+1)^p\equiv \sum _{i=0}^s C_s^i*x^{i*p}*\sum_{j=0}^qC_q^j*x^j$
而後考慮把兩邊的多項式展開一下
那麼兩邊確定都有$x^m$即$x^{t*p+r}$這一項(這是最上面的假設)
左邊的$x^m$的係數,根據上面的性質4推出來,應該是$C_n^m$
而後右邊嘞?只有$i=t,j=r$的時候纔會有這一項,因此這一項的係數就是$C_s^t*C_q^r$
而後又由於$s=n/p,t=n\%p,q=m/p,r=m\%p$
而後就能證實$C_n^m\equiv C_{n/p}^{m/p}*C_{n\%p}^{m\%p}(mod\ p)$
然而萬一$q<r$該怎麼辦?那樣的話$j$根本不可能等於$r$啊?
因此那樣的話答案就是$0$
由於上面乘上$C_{n\%p}^{m\%p}$答案就是$0$
如何證實?
咱們設$f=n-m=z*p+x$
由於$r>t,x+r\equiv t(mod\ p)$
因此$x+r=p+t$
又由於$z*p+x+q*p+r=s*p+t$
因此$z+q=s-1$
那麼帶進通項公式$C_n^m=\frac {n!}{m!*f!}$以後,分子中有$s$個$p$的倍數(不考慮有$p^2$之類的,由於下面有的話上面確定也有),分母中有$s-1$個$p$的倍數,抵消以後分子中還有一個$p$,那麼這個數就是$p$的倍數,模$p$確定餘$0$啦
累死我了……
1 // luogu-judger-enable-o2 2 //minamoto 3 #include<iostream> 4 #include<cstdio> 5 #define ll long long 6 using namespace std; 7 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++) 8 char buf[1<<21],*p1=buf,*p2=buf; 9 inline ll read(){ 10 #define num ch-'0' 11 char ch;bool flag=0;ll res; 12 while(!isdigit(ch=getc())) 13 (ch=='-')&&(flag=true); 14 for(res=num;isdigit(ch=getc());res=res*10+num); 15 (flag)&&(res=-res); 16 #undef num 17 return res; 18 } 19 const int N=100005; 20 ll n,m,p; 21 ll fac[N],inv[N]; 22 void init(){ 23 fac[0]=1; 24 for(int i=1;i<=p;++i) 25 fac[i]=fac[i-1]*i%p; 26 } 27 ll qpow(ll a,ll b){ 28 ll res=1; 29 while(b){ 30 if(b&1) res=res*a%p; 31 b>>=1,a=a*a%p; 32 } 33 return res; 34 } 35 ll C(ll n,ll m){ 36 if(m>n) return 0; 37 return fac[n]*qpow(fac[m]*fac[n-m],p-2)%p; 38 } 39 ll Lucas(ll n,ll m){ 40 if(m==0) return 1; 41 return Lucas(n/p,m/p)*C(n%p,m%p)%p; 42 } 43 int main(){ 44 int T=read(); 45 while(T--){ 46 n=read(),m=read(),p=read(); 47 init(); 48 printf("%lld\n",Lucas(m+n,m)); 49 } 50 return 0; 51 }