zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    WampServer Mysql配置
    Java实现 蓝桥杯VIP 算法提高 陶陶摘苹果2
    Java实现 蓝桥杯VIP 算法提高 陶陶摘苹果2
    Java实现 蓝桥杯VIP 算法提高 陶陶摘苹果2
    Java实现 蓝桥杯VIP 算法提高 质因数2
    Java实现 蓝桥杯VIP 算法提高 质因数2
    Java实现 蓝桥杯VIP 算法提高 质因数2
    Java实现 蓝桥杯VIP 算法提高 质因数2
    Java实现 蓝桥杯VIP 算法提高 质因数2
    Java实现 蓝桥杯VIP 算法提高 前10名
  • 原文地址:https://www.cnblogs.com/wsy01/p/8018444.html
Copyright © 2011-2022 走看看