zoukankan      html  css  js  c++  java
  • [bzoj2142]礼物——扩展卢卡斯定理

    题目大意:

    一年一度的圣诞节快要来到了。每年的圣诞节小E都会收到许多礼物,当然他也会送出许多礼物。不同的人物在小E心目中的重要性不同,在小E心中分量越重的人,收到的礼物会越多。小E从商店中购买了n件礼物,打算送给m个人,其中送给第i个人礼物数量为wi。请你帮忙计算出送礼物的方案数(两个方案被认为是不同的,当且仅当存在某个人在这两种方案中收到的礼物不同)。由于方案数可能会很大,你只需要输出模P后的结果。

    思路:

    拓展卢卡斯定理的裸体,直接上模板即可。

    #include<bits/stdc++.h>
     
    #define REP(i,a,b) for(int i=a,i##_end_=b;i<=i##_end_;++i)
    #define DREP(i,a,b) for(int i=a,i##_end_=b;i>=i##_end_;--i)
    #define MREP(i,x) for(int i=beg[x],v;v=to[i],i;i=las[i])
    #define debug(x) cout<<#x<<"="<<x<<endl
    #define fi first
    #define se second
    #define mk make_pair
    #define pb push_back
    typedef long long ll;
     
    using namespace std;
     
    void File(){
        freopen("bzoj2142.in","r",stdin);
        freopen("bzoj2142.out","w",stdout);
    }
     
    template<typename T>void read(T &_){
        T __=0,mul=1; char ch=getchar();
        while(!isdigit(ch)){
            if(ch=='-')mul=-1;
            ch=getchar();
        }
        while(isdigit(ch))__=(__<<1)+(__<<3)+(ch^'0'),ch=getchar();
        _=__*mul;
    }
     
    const int maxn=1e5+10;
    int m,tot;
    ll n,p,w[maxn],d[maxn],a[maxn],c[maxn];
     
    namespace ex{
        void exgcd(ll a,ll b,ll &x,ll &y){
            if(!b)x=1,y=0;
            else exgcd(b,a%b,y,x),y-=a/b*x;
        }
        ll inv(ll x,ll mod){
            ll a,b; exgcd(x,mod,a,b);
            return (a%mod+mod)%mod;
        }
    }
     
    ll qpow(ll x,ll y,ll mod){
        ll ret=1; x%=mod;
        while(y){
            if(y&1)ret=ret*x%mod;
            x=x*x%mod;
            y>>=1;
        }
        return ret;
    }
     
    ll Count(ll x,ll y){
        ll ret=0;
        while(x)ret+=x/y,x/=y;
        return ret;
    }
     
    ll Fac(ll x,ll y,ll mod){
        if(!x)return 1;
        ll ret=1;
        REP(i,1,mod)if(i%y)ret=ret*i%mod;
        ret=qpow(ret,x/mod,mod);
        REP(i,1,x%mod)if(i%y)ret=ret*i%mod;
        return Fac(x/y,y,mod)*ret%mod;
    }
     
    ll calc(ll x,ll y){
        ll ret=0;
        REP(i,1,tot){
            c[i]=qpow(d[i],Count(x,d[i])-Count(y,d[i])-Count(x-y,d[i]),a[i]);
            c[i]=c[i]*Fac(x,d[i],a[i])%a[i];
            c[i]=c[i]*ex::inv(Fac(y,d[i],a[i])*Fac(x-y,d[i],a[i])%a[i],a[i]);
            ret=(ret+p/a[i]*ex::inv(p/a[i],a[i])*c[i])%p;
        }
        return (ret+p)%p;
    }
     
    void init(){
        read(p);
        read(n),read(m);
        ll sum=0;
        REP(i,1,m)read(w[i]),sum+=w[i];
        if(sum>n)printf("Impossible"),exit(0);
        ll tmp=p;
        REP(i,2,1e5)if(tmp%i==0){
            d[++tot]=i,a[tot]=1;
            while(tmp%i==0)tmp/=i,a[tot]*=i;
        }
    }
     
    void work(){
        ll ans=1;
        REP(i,1,m){
            ans=ans*calc(n,w[i])%p;
            n-=w[i];
        }
        printf("%lld
    ",ans);
    }
     
    int main(){
        //File();
        init();
        work();
        return 0;
    }
    
    
  • 相关阅读:
    Loadrunner将字符串存为参数
    loadrnner添加C语言代码的几种方式
    Jmeter分布式
    Java jmx的使用
    Jmeter关联之正则表达式提取器(完整版)
    性能测试基础概念
    Jmeter实现百分比业务比例
    js闭包与java内部类
    程序员的足球
    虚拟机下Linux读取USB设备的问题虚拟机下Linux无法读取USB设备的解决方案
  • 原文地址:https://www.cnblogs.com/ylsoi/p/10098046.html
Copyright © 2011-2022 走看看