拓展Lucas
1 #include<cstdio> 2 #include<cstdlib> 3 #include<algorithm> 4 #include<cstring> 5 #include<vector> 6 #define MAXN 100000+10 7 #define ll long long 8 #define pb push_back 9 #define ft first 10 #define sc second 11 #define mp make_pair 12 using namespace std; 13 void extgcd(ll a,ll b,ll &x,ll &y){ 14 if(!b){x=1,y=0;} 15 else{ 16 ll xx,yy; 17 extgcd(b,a%b,xx,yy); 18 x=yy; 19 y=xx-a/b*yy; 20 } 21 } 22 ll Inv(ll a,ll b){ 23 ll x,y; 24 extgcd(a,b,x,y); 25 x=(x%b+b)%b; 26 if(!x)x+=b; 27 return x; 28 } 29 ll Pow(ll a,ll b,ll p){ 30 ll ret=1LL; 31 while(b){ 32 if(b&1){(ret*=a)%=p;} 33 (a*=a)%=p; 34 b>>=1; 35 } 36 return ret; 37 } 38 ll fac(ll n,ll pi,ll pk){ 39 if(!n)return 1LL; 40 ll ret=1LL; 41 for(ll i=2;i<pk;i++){ 42 if(i%pi)(ret*=i)%=pk; 43 } 44 ret=Pow(ret,n/pk,pk); 45 for(ll i=2;i<=(n%pk);i++){ 46 if(i%pi)(ret*=i)%=pk; 47 } 48 return ret*fac(n/pi,pi,pk)%pk; 49 //每隔pi拿走一个,所以是n/pi,不是n/pk 50 } 51 ll C(ll n,ll m,ll pi,ll pk){ 52 ll a=fac(n,pi,pk),b=fac(m,pi,pk),c=fac(n-m,pi,pk); 53 ll t=0LL; 54 for(ll i=n/pi;i;i/=pi)t+=i; 55 for(ll i=m/pi;i;i/=pi)t-=i; 56 for(ll i=(n-m)/pi;i;i/=pi)t-=i; 57 ll ret=a*Inv(b,pk)*Inv(c,pk)%pk; 58 (ret*=Pow(pi,t,pk))%=pk; 59 return ret; 60 } 61 ll n,m,p; 62 int main() 63 { 64 ll ans=0LL; 65 scanf("%lld%lld%lld",&n,&m,&p); 66 for(ll x=p,i=2;i<=p;i++){ 67 if(x%i==0){ 68 ll pk=1; 69 while(x%i==0){ 70 pk*=i; 71 x/=i; 72 } 73 ll t=C(n,m,i,pk); 74 (t*=(p/pk))%=p; 75 (t*=Inv(p/pk,pk))%=p; 76 (ans+=t)%=p; 77 } 78 } 79 printf("%lld\n",ans); 80 return 0; 81 }