• [cf2015ICLFinalsDiv1J]Ceizenpok’s formula


    题意:$C_n^m\% k$

    解题关键:扩展lucas+中国剩余定理裸题

     1 #include<algorithm>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<cstdio>
     5 #include<cmath>
     6 #include<cstdlib>
     7 typedef long long ll;
     8 using namespace std;
     9 ll mod,n,m,x,y,module[10002],piset[10002],r[10002];
    10 
    11 ll mod_pow(ll x,ll n,ll p){
    12     ll res=1;
    13     while(n){
    14         if(n&1) res=res*x%p;
    15         x=x*x%p;
    16         n>>=1;
    17     }
    18     return res;
    19 }
    20 
    21 ll extgcd(ll a,ll b,ll &x,ll &y){
    22     ll d=a;
    23     if(b)  d=extgcd(b,a%b,y,x),y-=a/b*x;
    24     else x=1,y=0;
    25     return d;
    26 }
    27 
    28 ll inv(ll t,ll mod){ extgcd(t,mod,x,y);return (x+mod)%mod;}
    29 
    30 ll multi(ll n,ll pi,ll pk){//求非互质的部分 
    31     if (!n) return 1;
    32     ll ans=1;
    33     for (ll i=2;i<=pk;i++) if(i%pi) ans=ans*i%pk;
    34     ans=mod_pow(ans,n/pk,pk);
    35     for (ll i=2;i<=n%pk;i++) if(i%pi) ans=ans*i%pk;
    36     return ans*multi(n/pi,pi,pk)%pk;
    37 }
    38 
    39 
    40 ll exlucas(ll n,ll m,ll pi,ll pk){//组合数 c(n,m)mod pk=pi^k 
    41     if(m>n) return 0;
    42     ll a=multi(n,pi,pk),b=multi(m,pi,pk),c=multi(n-m,pi,pk);
    43     ll k=0;
    44     for(ll i=n;i;i/=pi) k+=i/pi;
    45     for(ll i=m;i;i/=pi) k-=i/pi;
    46     for(ll i=n-m;i;i/=pi) k-=i/pi;
    47     return a*inv(b,pk)%pk*inv(c,pk)%pk*mod_pow(pi,k,pk)%pk;//组合数求解完毕 
    48 }
    49 
    50 ll crt(int n,ll *r,ll *m){
    51     ll M=1,ret=0;
    52     for(int i=0;i<n;i++) M*=m[i];
    53     for(int i=0;i<n;i++){
    54         ll w=M/m[i];
    55         ret+=w*inv(w,m[i])*r[i];
    56         ret%=M;
    57     }
    58     return (ret+M)%M;
    59 }
    60 
    61 ll fz(ll n,ll *m,ll *piset){//分解质因子 
    62     ll num=0;
    63     for (ll i=2;i*i<=n;i++){
    64         if(n%i==0){
    65             ll pk=1;
    66             while(n%i==0) pk*=i,n/=i;
    67             m[num]=pk;
    68             piset[num]=i;
    69             num++;
    70         }
    71     }
    72     if(n>1) m[num]=n,piset[num]=n,num++;
    73     return num;
    74 }
    75 
    76 ll excomb(ll n,ll m,ll p){
    77     ll num=fz(p,module,piset);
    78     for(int i=0;i<num;i++){
    79         r[i]=exlucas(n,m,piset[i],module[i]);
    80     }
    81     return crt(num,r,module);
    82 }
    83 
    84 int main(){
    85     cin>>n>>m>>mod;
    86     printf("%d",excomb(n,m,mod));
    87     return 0;
    88 }
  • 相关阅读:
    AtCoder Regular Contest 061
    Codeforces Round #370 (Div. 2)
    2016 ACM/ICPC Asia Regional Dalian Online
    HDU 5513 Efficient Tree
    Codeforces Round #104 (Div. 1)
    2016 Hunan Province Programming Contest
    2016 Multi-University Training Contest 7
    2016中国大学生程序设计竞赛
    聚会「AHOI 2008」
    游戏「AHOI / HNOI2018」
  • 原文地址:https://www.cnblogs.com/elpsycongroo/p/7620389.html
Copyright © 2020-2023  润新知