• bzoj2839: 集合计数 容斥+组合


    2839: 集合计数

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 523  Solved: 287
    [Submit][Status][Discuss]

    Description

    一个有N个元素的集合有2^N个不同子集(包含空集),现在要在这2^N个集合中取出若干集合(至少一个),使得

    它们的交集的元素个数为K,求取法的方案数,答案模1000000007。(是质数喔~)

    Input

    一行两个整数N,K

    Output

    一行为答案。

    Sample Input

    3 2

    Sample Output

    6

    HINT

    【样例说明】
    假设原集合为{A,B,C}
    则满足条件的方案为:{AB,ABC},{AC,ABC},{BC,ABC},{AB},{AC},{BC}
    【数据说明】
         对于100%的数据,1≤N≤1000000;0≤K≤N;

     

    选出k个重合元素的集合的方案数
    首先是k个元素的选择C(n,k)
    再考虑其他元素不交的方案m
    容斥: m=任意选集合的方案数-C(n-k,1)交集至少为1的方案+C(n-k,2)交集至少为2的方案...
    ans=C(n,k)*sum(C(n-k,i)*(2^(2^(n-i-k))-1))  0<=i<=n-k
    i=0是任意选的方案数
    处理组合数可以用公式
    其中涉及逆元,可以用递推求逆元数组
    因为mod是一个质数,也可以考虑费马小定理

    推荐blog
    https://www.cnblogs.com/candy99/p/6613808.html

    /*
    选出k个重合元素的集合的方案数
    首先是k个元素的选择C(n,k)
    再考虑其他元素不交的方案m 
    容斥: m=任意选集合的方案数-C(n-k,1)交集至少为1的方案+C(n-k,2)交集至少为2的方案... 
    ans=C(n,k)*sum(C(n-k,i)*(2^(2^(n-i-k))-1))  0<=i<=n-k
    i=0是任意选的方案数 
    处理组合数可以用公式
    其中涉及逆元,可以用递推求逆元数组
    因为mod是一个质数,也可以考虑费马小定理 
    
    推荐blog 
    https://www.cnblogs.com/candy99/p/6613808.html
    */
    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #define ll long long
    #define N 1000100
    #define mod 1000000007
    using namespace std;
    int fac[N],n,k,now=2;
    
    ll quick(int a,int b){
        ll c=1;
        while(b){
            if(b&1)c=(c*a)%mod;
            a=(1ll*a*a)%mod;b>>=1;
        }
        return c;
    }
    
    int C(int n,int m){
        int ans=fac[n];
        ll div1=quick(fac[m],mod-2);
        ll div2=quick(fac[n-m],mod-2);
        ans=(ans*div1)%mod;
        ans=(ans*div2)%mod;
        return ans;
    }
    int main(){
        scanf("%d%d",&n,&k);
        fac[0]=1;
        for(int i=1;i<=n;i++)
        fac[i]=(1ll*fac[i-1]*i)%mod;
        n-=k;ll ans=0;
        for(int i=n;~i;i--){
            (ans+=1ll*(i&1?-1:1)*C(n,i)*(now-1))%=mod;
            now=(1ll*now*now)%mod;
        }
        ans=(ans*C(n+k,k))%mod;
        ans<0?ans+=mod:1;
        cout<<ans;
        return 0;
    }
  • 相关阅读:
    R--相关分布函数、统计函数的使用
    Spark Streaming
    统计与分布的相关知识
    Python--WebDriverWait+expected_conditions的一个应用
    Python+Selenium与Chrome如何进行完美结合
    Python+Selenium+Chrome 的一个案例
    python -使用Requests库完成Post表单操作
    JetBrains PyCharm 2018.2.4 x64 工具里如何安装bs4
    用JetBrains PyCharm 开发工具写一个简单python案例
    dom4j学习总结(一)
  • 原文地址:https://www.cnblogs.com/wsy01/p/8018444.html
Copyright © 2020-2023  润新知