解析:首先,将m做质因数分解:m=p1*p2*p3。。。。(pi=ai^ti)
然后用扩展lucas定理求解:b[i]=c(n,m)%pi
然后用中国剩余定理进行合并,即可得解。
代码:
#include<cstdio>
using namespace std;
typedef long long LL;
LL pow_mod(LL x,LL y,LL p)
{
LL ans=1;
while(y>0)
{
if(y&1)ans=ans*x%p;
x=x*x%p,y>>=1;
}
return ans;
}
LL c1(LL n,LL p,LL pk)
{
if(n==0)return 1;
LL i,j,k,ans=1;
for(i=2;i<=pk;i++)if(i%p)ans=ans*i%pk;
ans=pow_mod(ans,n/pk,pk);
for(k=n%pk,i=2;i<=k;i++)if(i%p)ans=ans*i%pk;
return ans*c1(n/p,p,pk)%pk;
}
LL reverse(LL a,LL m)
{
if(a==0)return 0;
LL y=0,x=1,r=a%m,q,t,mm=m;
if(r<0)r+=m;
while((m%r)!=0)
{
a=m,m=r,q=a/m,r=a%m;
t=x,x=y-x*q,y=t;
}
if(r!=1)return 0;
if(x<0)x+=mm;
return x;
}
LL cal(LL n,LL m,LL p,LL pi,LL pk)
{
LL i,j,k=0,a,b,c,ans;
a=c1(n,pi,pk),b=c1(m,pi,pk),c=c1(n-m,pi,pk);
for(i=n;i;i/=pi)k+=i/pi;
for(i=m;i;i/=pi)k-=i/pi;
for(i=n-m;i;i/=pi)k-=i/pi;
ans=a*reverse(b,pk)%pk*reverse(c,pk)%pk*pow_mod(pi,k,pk)%pk;
return ans*(p/pk)%p*reverse(p/pk,pk)%p;
}
int main()
{
LL n,m,p,ans=0,x,i,j,k;
scanf("%I64d%I64d%I64d",&n,&m,&p);
for(x=p,i=2;x>1;i++)if(x%i==0)
{
for(k=1;x%i==0;x/=i)k*=i;
ans=(ans+cal(n,m,p,i,k))%p;
}
printf("%I64d\n",ans);
}