zoukankan      html  css  js  c++  java
  • [组合数学][容斥]集合计数

    首先我们知考虑只有一种交集

    交集的大小为K,那么有2N-K个子集包含了这K个元素(确定K个元素,再从剩下N-K个元素任意选取,有2N-K种组合)

    用这2N-K个子集能有2^(2^(N-K))种组合,再减去1个空集

    一共有CKN种交集,这样得出tmp(K)=CKN *(2^(2^(N-K)-1)种方法

    这里面包含了交集大小大于K的取法,所以还要进行容斥

    对于交集大小为L,有tmp(L)=CLN *(2^(2^(N-L)-1)种取法

    但是tmp(K)多的不止一倍的tmp(L),因为对于每一种交集都多加了tmp(L)

    多出CKL 

    例如:

      集合为{A,B,C,D,E},K=2

      tmp(K)包含了交集大小为K,K+1,K+2...N的取法种数

      合法的交集是AB,AC,AD...

      但是出现了像BCDE这样不合法的交集

      只计算交集为BC时多余BCDE交集,算BD,BE...同样多出

      所以BCDE被多算了C24

    容斥的话,L-N是奇数就减去CKL  *tmp(L),L-N是偶数就加上CKL  *tmp(L)

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 using namespace std;
     5 const long long p=(int)1e9+7;
     6 const int MAXN=(int)1e6+100;
     7 int N,K;
     8 long long fac[MAXN],faci[MAXN];
     9 long long qp[MAXN];   //2^2^i
    10 long long ans=0;
    11 long long qpow(long long a,long long b,long long p){
    12     if(a==0)
    13         return 0;
    14     a%=p;
    15     long long out=1;
    16     while(b){
    17         if(b&1)
    18              out=(out*a)%p;
    19         b>>=1;
    20         a=(a*a)%p;
    21     }
    22     return out;
    23 }
    24 
    25 long long C(int n,int m){
    26     if(m>n)
    27         return 0;
    28     return ((fac[n]*faci[m]%p)*faci[n-m])%p;
    29 }
    30 
    31 long long T(int i){    //2^(2^(N-i))
    32     return qp[N-i]-1;
    33 }
    34 
    35 int main(){
    36     scanf("%d%d",&N,&K);
    37     qp[0]=2;
    38     qp[1]=4;
    39     for(int i=2;i<=N;++i)
    40         qp[i]=qp[i-1]*qp[i-1]%p;
    41     fac[0]=faci[0]=1;
    42     for(int i=1;i<=N;++i)
    43         fac[i]=(fac[i-1]*i)%p;
    44     faci[N]=qpow(fac[N],p-2,p);
    45     for(int i=N-1;i>=1;--i)
    46         faci[i]=(faci[i+1]*(i+1))%p;
    47     ans=C(N,K)*T(K)%p;
    48     for(int i=K+1;i<=N;++i){
    49         long long fg=( (i-K) & 1 ) ? -1:1;
    50         ans+=(fg*C(i,K)*C(N,i)%p)*T(i)%p;
    51         ans=(ans+p)%p;
    52     }
    53     printf("%lld
    ",ans);
    54 }
    View Code
  • 相关阅读:
    VS.NET的新用途
    ASP.NET缓存引起的问题
    增加了查看最新回复功能
    高级浏览功能可以使用了
    转载JGTM'2004 [MVP]的文章
    首页文章字数统计改进
    请推荐好的工作流产品
    不错的工具:Reflector for .NET
    寻找文件同步软件
    javascript引起博客园首页不能显示问题说明
  • 原文地址:https://www.cnblogs.com/Duan-Yue/p/11127284.html
Copyright © 2011-2022 走看看