1. 程式人生 > >【Codeforces2015ICL,Finals,Div. 1#J】Ceizenpok's formula(擴充套件Lucas定理+中國剩餘定理)

【Codeforces2015ICL,Finals,Div. 1#J】Ceizenpok's formula(擴充套件Lucas定理+中國剩餘定理)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long LL;

LL ksm(LL a,LL b,LL mod)
{
    int ans=1;
    while(b)
    {
        if(b&1) ans=ans*a%mod;
        a=a*a%mod;
        b>>=1
; } return ans; } LL exgcd(LL a,LL b,LL &x,LL &y) { if(!b) {x=1;y=0;return a;} else exgcd(b,a%b,y,x),y-=a/b*x; } LL inv(LL a,LL mod) { if(!a) return 0; LL x,y; exgcd(a,mod,x,y); return (x%mod+mod)%mod; } LL mul(LL n,LL pi,LL pk) { if(!n) return 1ll; LL ans=1
ll; if(n/pk) { for(LL i=2;i<pk;i++) if(i%pi) ans=ans*i%pk; ans=ksm(ans,n/pk,pk); } for(LL i=2;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 mod,LL pi,LL pk) { if(m>n) return 0LL; LL a=mul(n,pi
,pk),b=mul(m,pi,pk),c=mul(n-m,pi,pk); LL k=0ll,ans; 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*ksm(pi,k,pk)%pk; return ans*(mod/pk)%mod*inv(mod/pk,pk)%mod; } LL exLucas(LL n,LL m,LL mod) { LL ans=0; for(LL x=mod,i=2;i<=mod;i++) if(x%i==0) { LL pk=1; while(x%i==0) pk*=i,x/=i; ans=(ans+C(n,m,mod,i,pk))%mod; } return ans; } int main() { LL n,m,mod; scanf("%lld%lld%lld",&n,&m,&mod); printf("%lld\n",exLucas(n,m,mod)); }