zoukankan      html  css  js  c++  java
  • luogu 5505 [JSOI2011]分特产 广义容斥

    共有 $m$ 种物品,每个物品 $a[i]$ 个,分给 $n$ 个人,每个人至少要拿到一件,求方案数.

    令 $f[i]$ 表示钦定 $i$ 个没分到特产,其余 $(n-i)$ 个人随便选的方案数,$g[i]$ 表示恰好 $i$ 个没分到特产的方案数.

    按照我们之前讲的,有 $f[k]=sum_{i=k}^{n}inom{k}{i}g[i]Rightarrow g[k]=sum_{i=k}^{n}(-1)^{i-k}inom{i}{k}f[i]$

    而根据定义,$f[i]=inom{n}{i} imes prod_{j=1}^{m}inom{a[j]+n-i-1}{n-i-1}$

    所以先预处理 $f[i]$,然后求 $g[0]$ 就好了(恰好 $0$ 个人没分到特产的方案数)

    code: 

    #include <bits/stdc++.h>   
    #define N 10005   
    #define LL long long 
    using namespace std;  
    const LL mod=1000000007;      
    void setIO(string s) 
    {
        string in=s+".in"; 
        string out=s+".out"; 
        freopen(in.c_str(),"r",stdin); 
    } 
    int a[N]; 
    LL fac[N],inv[N],f[N],g[N];    
    LL qpow(LL x,LL y) 
    {
        LL tmp=1ll; 
        for(;y;y>>=1,x=x*x%mod) 
            if(y&1) tmp=tmp*x%mod;  
        return tmp;   
    } 
    LL Inv(LL x) { return qpow(x,mod-2); } 
    LL C(int x,int y) 
    {
        return fac[x]*inv[y]%mod*inv[x-y]%mod;       
    }   
    int main() 
    { 
        // setIO("input");  
        int i,j,n,m; 
        fac[0]=inv[0]=1ll; 
        for(i=1;i<N;++i) fac[i]=fac[i-1]*1ll*i%mod,inv[i]=Inv(fac[i]);         
        scanf("%d%d",&n,&m); 
        for(i=1;i<=m;++i) scanf("%d",&a[i]);        
        for(i=0;i<=n;++i) 
        {      
            f[i]=C(n,i);   
            for(j=1;j<=m;++j) (f[i]=f[i]*C(a[j]+n-i-1,n-i-1)%mod)%=mod;   
        }    
        for(i=0;i<=n;++i)  
        {
            (g[0]+=qpow(-1,i)*f[i]%mod+mod)%=mod;     
        } 
        printf("%lld
    ",g[0]);   
        return 0;     
    }   
    

      

  • 相关阅读:
    感谢一个名叫“祯玥”的姑娘
    下一代互联网
    伤心时要读的三十八句
    任何企业的竞争,归根结底都是智能的竞争
    互联网创业必须过的槛(转)
    钻到牛角尖里面去,想开公司必需知道的奥秘
    重游草堂
    牛根生:我们应该学会“三换思维”
    领导者的感染力和传染力
    幸福是一种心境(转)
  • 原文地址:https://www.cnblogs.com/guangheli/p/11734770.html
Copyright © 2011-2022 走看看