• BZOJ


    扩展Lucas定理模板题(貌似这玩意也只能出模板题了吧~~本菜鸡见识鄙薄,有待指正)

    原理:

    https://blog.csdn.net/hqddm1253679098/article/details/82897638

    https://blog.csdn.net/clove_unique/article/details/54571216

    感觉扩展Lucas定理和Lucas定理的复杂程度差了不止一个档次,用到了一大堆莫名其妙的函数。

    另外谁能告诉我把一个很大的组合数对一个非质数取模有什么卵用

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const ll N=100;
     5 ll c[N],m[N],p[N],k[N],n,nn,mm[N],kk,pp;
     6 
     7 void exgcd(ll a,ll b,ll& x,ll& y,ll& g) {//扩展欧几里得
     8     if(!b)x=1,y=0,g=a;
     9     else exgcd(b,a%b,y,x,g),y-=x*(a/b);
    10 }
    11 ll inv(ll a,ll b) {//逆元
    12     ll x,y,g;
    13     exgcd(a,b,x,y,g);
    14     return x%b;
    15 }
    16 ll Pow(ll a,ll b,ll mod) {//快速幂
    17     ll ret=1;
    18     for(; b; b>>=1,a=a*a%mod)if(b&1)ret=ret*a%mod;
    19     return ret;
    20 }
    21 ll fact(ll n,ll p,ll k) {//求n!去掉质因子p后对p^k取模的值
    22     if(n==0)return 1;
    23     ll mod=Pow(p,k,10000000),ret=1,cnt=n/mod;
    24     for(ll i=1; i<=mod; ++i)if(i%p)ret=ret*i%mod;
    25     ret=Pow(ret,cnt,mod);
    26     for(ll i=n-cnt*mod; i>=1; --i)if(i%p)ret=ret*i%mod;
    27     return ret*fact(n/p,p,k)%mod;
    28 }
    29 ll C(ll n,ll m,ll p,ll k) {//求C(n,m)对p^k取模的值
    30     ll mod=Pow(p,k,10000000);
    31     ll ret=fact(n,p,k)*inv(fact(m,p,k),mod)%mod*inv(fact(n-m,p,k),mod)%mod;
    32     ll cnt=0;
    33     for(ll i=p; i<=n; i*=p)cnt+=n/i;
    34     for(ll i=p; i<=m; i*=p)cnt-=m/i;
    35     for(ll i=p; i<=n-m; i*=p)cnt-=(n-m)/i;
    36     if(cnt<0)ret=ret*inv(Pow(p,-cnt,mod),mod)%mod;
    37     else ret=ret*Pow(p,cnt,mod)%mod;
    38     return ret;
    39 }
    40 ll CRT(ll* c,ll* m,ll n) {//扩展中国剩余定理
    41     ll M=1,C=0,x,y,g;
    42     for(ll i=0; i<n; ++i) {
    43         exgcd(M,m[i],x,y,g);
    44         if((c[i]-C)%g)return -1;
    45         C=x%(m[i]/g)*((c[i]-C)/g)%(m[i]/g)*M+C;
    46         M=M*m[i]/g,C%=M;
    47     }
    48     return (C%M+M)%M;
    49 }
    50 void split(ll x) {//唯一分解定理
    51     n=0;
    52     for(ll i=2; i*i<=x; ++i)if(x%i==0) {
    53             p[n]=i,k[n]=0;
    54             while(x%i==0)x/=i,k[n]++;
    55             n++;
    56         }
    57     if(x>1)p[n]=x,k[n++]=1;
    58 }
    59 ll C(ll nn,ll mm,ll P) {//计算C(nn,mm)%P
    60     split(P);
    61     for(ll i=0; i<n; ++i)m[i]=Pow(p[i],k[i],10000000),c[i]=C(nn,mm,p[i],k[i]);
    62     return CRT(c,m,n);
    63 }
    64 ll solve() {
    65     if(accumulate(mm,mm+kk,0ll)>nn)return -1;
    66     ll ret=1;
    67     for(ll i=0; i<kk; ++i)ret=ret*C(nn,mm[i],pp)%pp,nn-=mm[i];
    68     return ret;
    69 }
    70 int main() {
    71     while(scanf("%lld",&pp)==1) {
    72         scanf("%lld%lld",&nn,&kk);
    73         for(ll i=0; i<kk; ++i)scanf("%lld",&mm[i]);
    74         ll ans=solve();
    75         if(!~ans)printf("Impossible
    ");
    76         else printf("%lld
    ",ans);
    77     }
    78     return 0;
    79 }
  • 相关阅读:
    字符串-01. 在字符串中查找指定字符(15)
    数组-14. 数字加密(15)
    软考笔记第一天之数制
    基于c#开发的简易点名器
    软考笔记之存储管理
    IO inputStream和outputStream
    java可变参数
    Map集合总结
    Collection集合总结
    Struts 获得前台传参几种方式
  • 原文地址:https://www.cnblogs.com/asdfsag/p/10440524.html
Copyright © 2020-2023  润新知