传送门

codeforces2015ICL,Finals,Div.1#J Ceizenpok’s formula【扩展lucas】-LMLPHP

codeforces2015ICL,Finals,Div.1#J Ceizenpok’s formula【扩展lucas】-LMLPHP

[题意]:

求C(n,k)%m,n<=10,k<=n,m<=10

[思路]:

扩展lucas定理+中国剩余定理

codeforces2015ICL,Finals,Div.1#J Ceizenpok’s formula【扩展lucas】-LMLPHP codeforces2015ICL,Finals,Div.1#J Ceizenpok’s formula【扩展lucas】-LMLPHP codeforces2015ICL,Finals,Div.1#J Ceizenpok’s formula【扩展lucas】-LMLPHP

#include<cstdio>
using namespace std;
typedef long long ll;
ll n,m,MOD,ans;
ll fpow(ll a,ll p,ll mod){
ll res=;
for(;p;p>>=,a=a*a%mod) if(p&) res=res*a%mod;
return res;
}
void exgcd(ll a,ll b,ll &d,ll &x,ll &y){
if(!b){d=a;x=;y=;return ;}
exgcd(b,a%b,d,y,x);
y-=a/b*x;
}
ll inv(ll a,ll p){
ll d,x,y;
exgcd(a,p,d,x,y);
return d==?(x%p+p)%p:-;
}
ll mul(ll n,ll pi,ll pk){
if(!n) return ;
ll ans=;
if(n/pk){
for(ll i=;i<=pk;i++) if(i%pi) ans=ans*i%pk;
ans=fpow(ans,n/pk,pk);
}
for(ll i=;i<=n%pk;i++) if(i%pi) ans=ans*i%pk;
return ans*mul(n/pi,pi,pk)%pk;
}
ll C(ll n,ll m,ll pi,ll pk,ll mod){
if(n<m) return ;
ll a=mul(n,pi,pk),b=mul(m,pi,pk),c=mul(n-m,pi,pk);
ll ans,k();
for(ll i=n;i;i/=pi) k+=i/pi;
for(ll i=m;i;i/=pi) k-=i/pi;
for(ll i=n-m;i;i/=pi) k-=i/pi;
ans=a*inv(b,pk)%pk*inv(c,pk)%pk*fpow(pi,k,pk)%pk;
return ans*(mod/pk)%mod*inv(mod/pk,pk)%mod;
}
int main(){
scanf("%I64d%I64d%I64d",&n,&m,&MOD);
ll x=MOD;
for(ll pk,i=;i*i<=MOD;i++){
if(!(x%i)){
pk=;
while(!(x%i)) pk*=i,x/=i;
ans=(ans+C(n,m,i,pk,MOD))%MOD;
}
}
if(x>) ans=(ans+C(n,m,x,x,MOD))%MOD;
printf("%I64d\n",ans);
return ;
}
05-03 22:31