zoukankan      html  css  js  c++  java
  • 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 }

      

  • 相关阅读:
    shell学习(15)- eval及shell No such file or directory解决办法
    30张图带你彻底理解红黑树
    linux中$@,$*,$0,$$,$?参数的含义
    QPS,TPS,吞吐量,响应时间详解及关系
    shell学习(14)- who
    SpringBoot 入门
    创建 Java 项目
    部分 GIT 命令
    Spark Executor Task 的执行和数量
    Ubuntu 18 单机安装 HDP 3
  • 原文地址:https://www.cnblogs.com/ezyzy/p/6529417.html
Copyright © 2011-2022 走看看