实在看不惯自己以前的代码风格,改了一下。。。
#include <cstdio>
#include <iostream>
using namespace std;
inline int add(int a,int b,int p)
{a+=b;return a>=p?a-p:a;}
inline int ch(int a,int b,int p)
{return 1LL*a*b%p;}
inline int ksm(int a,int b,int p)
{
int ans=1;
while(b)
{
if(b&1)ans=ch(ans,a,p);
a=ch(a,a,p),b>>=1;
}
return ans;
}
int MOD;
int fAC(int n,int p,int ct)
{
if(!n)return 1;
int res=n%ct,t=1;
for(int i=2;i<ct;i++)
if(i%p>0)t=ch(t,i,ct);
t=ksm(t,n/ct,ct);
for(int i=2;i<=res;i++)
if(i%p>0)t=ch(t,i,ct);
return ch(fAC(n/p,p,ct),t,ct);
}
int C(int n,int m,int p,int ct)
{
if(n<m)return 0;
int tx=fAC(n,p,ct),ty=fAC(m,p,ct),tz=fAC(n-m,p,ct),co=0;
for(int i=n;i;i/=p)co+=i/p;
for(int i=m;i;i/=p)co-=i/p;
for(int i=n-m;i;i/=p)co-=i/p;
int phi=ct-ct/p;
return ch(ch(tx,ch(ksm(ty,phi-1,ct),ksm(tz,phi-1,ct),ct),ct),ksm(p,co,ct),ct);
}
int luc(int n,int m,int MOD)
{
int x=MOD,ans=0;
for(int i=2;i*i<=x;i++)
if(x%i==0)
{
int cnt=1;
while(x%i==0)x/=i,cnt*=i;
int get=C(n,m,i,cnt),m=MOD/cnt;
ans=add(ans,ch(ch(m,ksm(m,cnt-cnt/i-1,cnt),MOD),get,MOD),MOD);
}
if(x>1)
{
int cnt=x,i=x;
int get=C(n,m,i,cnt),m=MOD/cnt;
ans=add(ans,ch(ch(m,ksm(m,cnt-cnt/i-1,cnt),MOD),get,MOD),MOD);
}
return ans;
}
int main()
{
int n,m,p;
cin>>n>>m>>p;
cout<<luc(n,m,p);
return 0;
}