题目

一个有 \(N\) 个 元素的集合有 \(2^N\) 个不同子集(包含空集),

现在要在这 \(2^N\) 个集合中取出若干集合(至少一个),

使得它们的交集的元素个数为 \(K\) ,求取法的方案数,答案模 \(1000000007\) 。

\((1 \le N \le 10^6, 0 \le K \le N)\)

题解

又是一道 裸的 广义容斥定理 还没这道题难qwq

广义容斥定理 (二项式反演) :

\[\displaystyle b_k = \sum_{i=k}^n \binom i k a_i
\]

\[\Updownarrow
\]

\[\displaystyle a_k = \sum_{i=k}^{n} (-1)^{i-k} \binom i k b_i
\]

不难发现又是一个恰好 我们转化成至少就行了

那么交集有至少 \(i\) 个集合的个数 \(b_i\) 就是

\[\displaystyle b_i = \binom n i 2^{2^{n-i}}
\]

一开始我以为后面那个直接是 \(2^{n-i}\) .... 没过样例搜了波题解... 发现是 \(2^{2^{n-i}}\) qwq

为什么呢 我们这样考虑 当前枚举了一个大小为 \(i\) 交集后 还剩下 \(n-i\) 个元素

每个元素有选和不选的两种方案 那么共有 \(2^{n-i}\) 个互不相同的集合

那么每个集合我们又有选和不选两种方案 那么总共就是 \(2^{2^{n-i}}\) 种咯qwq

然后套上去 答案就是

\[\displaystyle \mathrm{ans} = \sum_{i=k}^{n} (-1)^{i-k} \binom i k b_i
\]

代码

#include <bits/stdc++.h>
#define For(i, l, r) for(register int i = (l), i##end = (int)(r); i <= i##end; ++i)
#define Fordown(i, r, l) for(register int i = (r), i##end = (int)(l); i >= i##end; --i)
#define Set(a, v) memset(a, v, sizeof(a))
using namespace std; inline bool chkmin(int &a, int b) {return b < a ? a = b, 1 : 0;}
inline bool chkmax(int &a, int b) {return b > a ? a = b, 1 : 0;} inline int read() {
int x = 0, fh = 1; char ch = getchar();
for (; !isdigit(ch); ch = getchar()) if (ch == '-') fh = -1;
for (; isdigit(ch); ch = getchar()) x = (x * 10) + (ch ^ 48);
return x * fh;
} void File() {
#ifdef zjp_shadow
freopen ("P2839.in", "r", stdin);
freopen ("P2839.out", "w", stdout);
#endif
} typedef long long ll;
const ll Mod = 1e9 + 7;
ll fpm(ll x, int power) {
ll res = 1;
for (; power; power >>= 1, (x *= x) %= Mod)
if (power & 1) (res *= x) %= Mod;
return res;
} const int N = 1e6;
ll fac[N + 100], ifac[N + 100], pow2[N + 100], ppow2[N + 100];
void Init(int maxn) {
fac[0] = ifac[0] = pow2[0] = ppow2[0] = 1;
For (i, 1, maxn) fac[i] = fac[i - 1] * i % Mod, pow2[i] = pow2[i - 1] * 2 % Mod, ppow2[i] = ppow2[i - 1] * 2 % (Mod - 1);
ifac[maxn] = fpm(fac[maxn], Mod - 2);
Fordown (i, maxn - 1, 1) ifac[i] = ifac[i + 1] * (i + 1) % Mod;
} ll ans = 0; ll C(int n, int m) {
if (n < 0 || m < 0 || n < m) return 0;
return fac[n] * ifac[m] % Mod * ifac[n - m] % Mod;
} int main () {
File();
Init(N);
int n = read(), k = read();
For (i, k, n)
(ans += Mod + ((i - k) & 1 ? -1 : 1) * (C(i, k) * C(n, i) % Mod * fpm(2, ppow2[n - i]) % Mod)) %= Mod;
printf ("%lld\n", ans);
return 0;
}

BZOJ2839 : 集合计数 (广义容斥定理)的更多相关文章

  1. bzoj2839 集合计数(容斥)

    2839: 集合计数 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 883  Solved: 490[Submit][Status][Discuss] ...

  2. bzoj2839 集合计数(容斥+组合)

    集合计数 内存限制:128 MiB 时间限制:1000 ms 标准输入输出     题目描述 一个有N个元素的集合有2^N个不同子集(包含空集),现在要在这2^N个集合中取出若干集合(至少一个),使得 ...

  3. BZOJ 2839: 集合计数 广义容斥

    在一个 $N$ 个元素集合中的所有子集中选择若干个,且交集大小为 $k$ 的方案数. 按照之前的套路,令 $f[k]$ 表示钦定交集大小为 $k$,其余随便选的方案数. 令 $g[k]$ 表示交集恰好 ...

  4. 【BZOJ2839】集合计数(容斥,动态规划)

    [BZOJ2839]集合计数(容斥,动态规划) 题面 BZOJ 权限题 Description 一个有N个元素的集合有2^N个不同子集(包含空集),现在要在这2^N个集合中取出若干集合(至少一个),使 ...

  5. 【BZOJ2839】集合计数 组合数+容斥

    [BZOJ2839]集合计数 Description 一个有N个元素的集合有2^N个不同子集(包含空集),现在要在这2^N个集合中取出若干集合(至少一个),使得它们的交集的元素个数为K,求取法的方案数 ...

  6. bzoj 2839 集合计数 容斥\广义容斥

    LINK:集合计数 容斥简单题 却引出我对广义容斥的深思. 一直以来我都不理解广义容斥是为什么 在什么情况下使用. 给一张图: 这张图想要表达的意思就是这道题目的意思 而求的东西也和题目一致. 特点: ...

  7. How Many Sets I(容斥定理)

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3556 How Many Sets I Time Limit: 2 ...

  8. UVA-11806 Cheerleaders 计数问题 容斥定理

    题目链接:https://cn.vjudge.net/problem/UVA-11806 题意 在一个mn的矩形网格里放k个石子,问有多少方法. 每个格子只能放一个石头,每个石头都要放,且第一行.最后 ...

  9. 51nod1284容斥定理

    1284 2 3 5 7的倍数 基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题   给出一个数N,求1至N中,有多少个数不是2 3 5 7的倍数. 例如N = 10, ...

随机推荐

  1. Python基础语法复习

    1.数据类型 List 列表 函数 append(): 在列表末尾追加. count(): 计算对象在列表中出现的次数. extend():将列表内容添加到列表中. index(): 计算对象在列表中 ...

  2. React-state props与render()的关系

    state或者props发生改变,render()j就会执行一次. 父组件的render()被重新执行时,它的子组件的render()都会重新执行.

  3. 重装系统之无法在驱动器0的分区1上安装windows

    在通过U盘或光盘安装win8/win8.1/win10 时,遇到无法安装的问题,提示“无法在驱动器0的分区1上安装windows”,格式化分区也不能解决,进而提示Windows无法安装到这个磁盘,选中 ...

  4. C# 获取电脑MAC地址,IP地址,物理内存,CPU序列号,硬盘ID..........................

    上班很忙,自己做个记录 代码如下: 需要引入:System.Management 代码如下: using System; using System.Collections.Generic; using ...

  5. linux 下隐藏进程的一种方法

    前言 本文所用到的工具在 https://github.com/gianlucaborello/libprocesshider 可以下载 思路就是利用 LD_PRELOAD 来实现系统函数的劫持 LD ...

  6. Mybatis 中 columnPrefix别名的用法

    1.映射对应的属性,区分他们分别属于哪些类.(sql书写的时候为什么要将前缀加上(别名),是因为便于它去寻找哪个类的前缀是ANNEX_) 2.例:  如下所示当一个collection 定义了一个co ...

  7. Linux下对文件进行加密备份的操作记录

    由于公司之前在阿里云上购买了一些机器,后续IDC建设好后,又将线上业务从阿里云上迁移到IDC机器上了,为了不浪费阿里云上的这几台机器资源,打算将这些机器做成IP SAN共享存储,然后作为IDC数据的一 ...

  8. C++ string简单的使用技巧

    截取substr //string的操作 #include<iostream> using namespace std; int main() { string a,b; a=" ...

  9. 对PS的评价

    Photoshop(简称:PS)是电脑上的图像处理软件:对于广大Photoshop爱好者而言,PS亦用来形容通过该类图形处理软件处理过的图片,即非原始.非未处理的图片:多数人对于这软件的了解仅限于“一 ...

  10. hash函数补分博客

    题目要求: 利用除留余数法为下列关键字集合的存储设计hash函数,并画出分别用开放寻址法和拉链法解决冲突得到的空间存储状态(散列因子取0.75) 关键字集合:85,75,57,60,65,(你的8位学 ...