zoukankan      html  css  js  c++  java
  • BZOJ 2839: 集合计数 广义容斥

    在一个 $N$ 个元素集合中的所有子集中选择若干个,且交集大小为 $k$ 的方案数.

    按照之前的套路,令 $f[k]$ 表示钦定交集大小为 $k$,其余随便选的方案数. 令 $g[k]$ 表示交集恰好为 $k$ 的方案数.
    则有 $f[k]=sum_{i=k}^{n}inom{i}{k}g[k]$,反演得 $g[k]=sum_{i=k}^{n}(-1)^{i-k}inom{i}{k}f[i]$
    而 $f[k]=inom{n}{k}2^{2^{n-k}}$,直接带入求值即可.

    code: 

    #include <bits/stdc++.h>   
    #define N 1000005   
    #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],poww[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,k; 
        fac[0]=inv[0]=poww[0]=1ll;           
        scanf("%d%d",&n,&k); 
        for(i=1;i<=n;++i) fac[i]=fac[i-1]*1ll*i%mod,inv[i]=Inv(fac[i]),poww[i]=poww[i-1]*2ll%(mod-1);
        for(i=0;i<=n;++i) f[i]=C(n,i)*qpow(2,poww[n-i])%mod;    
        LL ans=0ll;  
        for(i=k;i<=n;++i) (ans+=(qpow(-1,i-k)*C(i,k)%mod*f[i]%mod+mod)%mod)%=mod;  
        printf("%lld
    ",ans); 
        return 0;     
    }   
    

      

  • 相关阅读:
    最短路径的三种实现方法
    c/c++小知识
    c++ char * const p问题
    C++ typedef 四个用途
    [转]c++面向对象基础
    [转]C++中引用(&)的用法和应用实例
    表情包。
    linux基础学习
    redis缓存在项目中的使用
    关于redis
  • 原文地址:https://www.cnblogs.com/guangheli/p/11734882.html
Copyright © 2011-2022 走看看