zoukankan      html  css  js  c++  java
  • 【题解】国家集训队礼物(Lucas定理)

    [国家集训队]礼物(扩展Lucas定理)

    传送门可以直接戳标题
    172.40.23.20 24 .1
    答案就是一个式子:

    [{nchoose Sigma_{i=1}^m w} imesprod_{i=1}^m {Sigma_{j=1}^m w_j-Sigma_{j=1}^{j< i}w_jchoose w_i} ]

    解释一下这个式子怎么来的...

    • 先从所有的礼物里面选出(Sigma w)出来
    • 每个人依次选,选择的方案就是从剩下的礼物中挑出(w_i)

    直接扩展Lucas...

    #include<bits/stdc++.h>
    #define int long long 
    using namespace std;typedef long long ll;
    template < class ccf >
    inline ccf qr(ccf b){
        register char c=getchar();register int q=1;register ccf x=0;
        while(c<48||c>57)q=c==45?-1:q,c=getchar();
        while(c>=48&&c<=57)x=x*10+c-48,c=getchar();
        return q==-1?-x:x;}
    inline int qr(){return qr(1);}
    
    
    const int maxn=51;
    int n,mod,m;
    int w[maxn];
    
    
    namespace lcs{
        inline ll poww(ll a,ll b,ll mod){
        ll base=a,ans=1;
        while(b){
            if(b&1) ans=(1ll*ans*base)%mod;
            base=(1ll*base*base)%mod;
            b>>=1;
        }
        return 1ll*ans;
        }
    
        inline void Exgcd(ll a,ll b,ll &x,ll &y){
        if(!b){x=1,y=0;return ;}
        Exgcd(b,a%b,y,x);y-=a/b*x;
        }
        
        inline ll rev(ll k,ll p){
        if(!k)return 0;
        ll x=0,y=0,a=k,b=p;
        Exgcd(a,b,x,y);
        x=(x%b+b)%b;
        if(!x)x+=b;
        return 1ll*x;
        }
        inline ll mul(ll n,ll p,ll pk){
        if(!n)return 1;
        ll ans=1;
        for(ll i=2;i<=pk;i++)
            if(i%p)ans=ans*i%pk;
        ans=poww(ans,n/pk,pk);
        for(ll i=2;i<=n%pk;i++)
            if(i%p)ans=ans*i%pk;
        return 1ll*ans*mul(n/p,p,pk)%pk;
        }
        
        inline ll C(ll n,ll m,ll mod,ll p,ll pk){
        if(m>n)return 0;
        ll a=mul(n,p,pk),b=mul(m,p,pk),c=mul(n-m,p,pk),k=0;
        
        for(ll i=n;i;i/=p)k+=i/p;
        for(ll i=m;i;i/=p)k-=i/p;
        for(ll i=n-m;i;i/=p)k-=i/p;
    
        ll ans=1ll*a*rev(b,pk)%pk*rev(c,pk)%pk*poww(p,k,pk)%pk;
    
        return 1ll*ans*(mod/pk)%mod*rev(mod/pk,pk)%mod;
        }
        inline ll exlucas(int n,int m){
        int mod=::mod;
        int ret=0;
        for(register int t=2;t*t<=mod;++t)
            if(mod%t==0){
            register int temp=1;
            while(mod%t==0) temp*=t,mod/=t;
            ret=(ret+C(n,m,::mod,t,temp))%(::mod);
            }
        if(mod>1) ret=(ret+C(n,m,::mod,mod,mod))%(::mod);
        return ret;
        }
        
    }
    
    using lcs::exlucas;
    #undef int
    int main(){
    #define int long long
        // freopen("gift.in","r",stdin);
        // freopen("gift.out","w",stdout);
        mod=qr();
        n=qr();m=qr();
        for(register int t=1;t<=m;++t)
        w[t]=qr(),w[0]+=w[t];
        if(w[0]>n) return puts("Impossible"),0;
        ll ans=exlucas(n,w[0]);
        for(register int t=1;t<=m;++t)
        ans=ans*exlucas(w[0],w[t])%mod,w[0]-=w[t];
        printf("%lld
    ",(ll)ans);
        return 0;
    }
    
    
  • 相关阅读:
    JS获取本周、本季度、本月、上月的开始日期、结束日期
    《大教堂和集市》笔记——为什么一个本科生业余作品却成了全世界最流行的操作系统之一Linux?
    “平头哥”半导体公司
    阻挡不住的变化
    给我五分钟,带你走出迷茫
    涂子沛:从幼稚到成熟,我们这个时代的数据革命
    统计思维就是透过现象看本质
    十个有趣的“大数据”挖掘案例
    信息时代与大数据相关的8个专业
    大数据招聘分析
  • 原文地址:https://www.cnblogs.com/winlere/p/10805414.html
Copyright © 2011-2022 走看看