• bzoj 2839 : 集合计数 容斥原理


    因为要在n个里面选k个,所以我们先枚举选的是哪$k$个,方案数为$C_{n}^k$

    确定选哪k个之后就需要算出集合交集正为好这$k$个的方案数,考虑用容斥原理。

    我们还剩下$n-k$个元素,交集至少为$k$的方案数为$2^{2^{n-k}}$。

    相当于在仅有剩下$n-k$个元素的集合里随便选,最后再往每个集合里塞进这$k$个元素。

    然后就是很简单的容斥了。

    减去交集至少为k加上其他一个元素的方案数,加上交集至少为k加上其他两个元素的方案数。。。

    $$ans=C_{n}^k imes(2^{2^{n-k}}-C_{n-k}^1 imes 2^{2^{n-k-1}}+C_{n-k}^2 imes 2^{2^{n-k-2}}-.....)$$
    好像网上其他做法跟我不太一样呢。。。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #define N 1000005
     6 #define ll long long
     7 using namespace std;
     8 const int p = 1000000007;
     9 int n,k;
    10 ll pw(int x,int y)
    11 {
    12     ll lst=1;
    13     while(y)
    14     {
    15         if(y&1)lst=lst*x%p;
    16         y>>=1;
    17         x=(ll)x*x%p;
    18     }
    19     return lst;
    20 }
    21 int pow[N],jie[N];
    22 int main()
    23 {
    24     pow[0]=1;jie[0]=1;
    25     scanf("%d%d",&n,&k);
    26     for(int i=1;i<=n-k;i++)pow[i]=(pow[i-1]*2)%(p-1);
    27     for(int i=1;i<=n;i++)jie[i]=(1LL*jie[i-1]*i)%p;
    28     ll ans=0;
    29     ans=pw(2,pow[n-k]);
    30     for(int i=1;i<=n-k;i++)
    31     {
    32         int tmp=1LL*pw(2,pow[n-k-i])*jie[n-k]%p*pw(jie[i],p-2)%p*pw(jie[n-k-i],p-2)%p;
    33         if(i&1)ans=(ans-tmp+p)%p;
    34         else ans=(ans+tmp)%p;
    35     }
    36     ans=ans*jie[n]%p*pw(jie[k],p-2)%p*pw(jie[n-k],p-2)%p;
    37     printf("%lld
    ",ans);
    38     return 0;
    39 }

      

  • 相关阅读:
    JavaScript高级-----8.函数进阶(2)
    JavaScript高级-----7.函数进阶(1)
    2014-10-18 来美半个月
    修手机记
    圆梦美利坚之三:租房记
    圆梦美利坚之二:买机票记
    Hadoop 停止Job
    IIS应用程序池数目
    HTML5 microdata
    Java sql helper[转]
  • 原文地址:https://www.cnblogs.com/ezyzy/p/6529417.html
Copyright © 2020-2023  润新知