• luogu 4720 【模板】扩展卢卡斯


    题目大意:

    求$C_n^m mod p$,p不一定为质数

    思路:

    首先可以将$p$分解为$p1^{a1}*p2^{a2}*...*pk^{ak}$,对于这些部分可以使用$CRT$合并

    对于每个$p_i^{k_i}$,阶乘是存在循环的例如$19!$与模数$9$

    $1*2*4*5*7*8$与$10*11*13*14*16*17$对答案的贡献一样,因此可以快速幂

    对于剩下的部分因为很少可以暴力

    对于求阶乘的部分 用这种方法求出循环节和剩余部分然后继续递归即可

    求$C$的时候$C_n^m mod p^k= frac{n! / p^a}{m! / p^b imes (n-m)! / p^c} * p^{a-b-c} mod p^k$

    然后就是$CRT$套上述这一堆东西

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cstdlib>
     5 #include<cmath>
     6 #include<algorithm>
     7 #include<queue>
     8 #include<vector>
     9 #include<map>
    10 #include<set>
    11 #define ll long long
    12 #define db double
    13 #define inf 2139062143
    14 #define MAXN 200100
    15 #define rep(i,s,t) for(register int i=(s),i##__end=(t);i<=i##__end;++i)
    16 #define dwn(i,s,t) for(register int i=(s),i##__end=(t);i>=i##__end;--i)
    17 #define ren for(register int i=fst[x];i;i=nxt[i])
    18 #define pb(i,x) vec[i].push_back(x)
    19 #define pls(a,b) (a+b)%MOD
    20 #define mns(a,b) (a-b+MOD)%MOD
    21 #define mul(a,b) (1LL*(a)*(b))%MOD
    22 using namespace std;
    23 inline ll read()
    24 {
    25     ll x=0,f=1;char ch=getchar();
    26     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    27     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    28     return x*f;
    29 }
    30 ll T,n,m,MOD;
    31 ll q_pow(ll a,ll t,ll p,ll res=1)
    32 {
    33     for(a%=p;t;t>>=1,(a*=a)%=p)
    34         if(t&1) (res*=a)%=p;return res;
    35 }
    36 ll exgcd(ll a,ll b,ll &x,ll &y)
    37 {
    38     if(!b){x=1,y=0;return a;}
    39     ll d=exgcd(b,a%b,y,x);y-=(a/b)*x;return d;
    40 }
    41 ll pw(ll n,ll p,ll pk)
    42 {
    43     if(!n) return 1;ll res=1;
    44     rep(i,2,pk) if(i%p) (res*=i)%=pk;
    45     res=q_pow(res,n/pk,pk);
    46     rep(i,2,n%pk) if(i%p) (res*=i)%=pk;
    47     return (res*pw(n/p,p,pk))%pk;
    48 }
    49 ll inv(ll n,ll p) {ll x,y;exgcd(n,p,x,y);return (x+p)%p;}
    50 ll C(ll n,ll m,ll p,ll pk)
    51 {
    52     ll pn=pw(n,p,pk),pm=pw(m,p,pk),pz=pw(n-m,p,pk),sum=0;
    53     for(ll i=n;i;i/=p) sum+=i/p;for(ll i=m;i;i/=p) sum-=i/p;
    54     for(ll i=n-m;i;i/=p) sum-=i/p;
    55     pm=inv(pm,pk),pz=inv(pz,pk);
    56     return (((q_pow(p,sum,pk)*pn)%MOD*pm)%MOD*pz)%MOD;
    57 }
    58 void exlucas(ll n,ll m)
    59 {
    60     ll p=MOD,rs=p,k,ans=0,x,y;
    61     rep(i,2,sqrt(MOD))
    62     {
    63         k=1;while(rs%i==0) rs/=i,k*=i;
    64         if(k!=1) (ans+=(inv(p/k,k)*p/k)%MOD*C(n,m,i,k)+MOD)%=MOD;
    65     }
    66     if(rs!=1) (ans+=(inv(p/rs,rs)*p/rs)%MOD*C(n,m,rs,rs)+MOD)%=MOD;
    67     printf("%lld
    ",ans);
    68 }
    69 int main()
    70 {
    71     n=read(),m=read(),MOD=read();exlucas(n,m);
    72 }
    View Code
  • 相关阅读:
    移动端web
    递归求和
    json的基础了解
    冒泡排序的编程方法
    js面向对象
    1002,javascript的原型属性
    1001,instanceof关键字以及typeof关键字
    19,简述一下src与href的区别(不懂)
    531,<form>action属性
    530,css outline属性
  • 原文地址:https://www.cnblogs.com/yyc-jack-0920/p/10529530.html
Copyright © 2020-2023  润新知