codeforces Gym - 100633J Ceizenpok’s formula

拓展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 }

 

posted @ 2018-01-20 12:22  white_hat_hacker  阅读(188)  评论(0编辑  收藏  举报