P r o b l e m \mathrm{Problem} Problem

给出一个长度为n的序列 a 1 , a 2 . . . a n a_1,a_2...a_n a1​,a2​...an​。

求构造出一个序列 i 1 ≤ i 2 ≤ . . . ≤ i k ( 1 ≤ k ≤ n ) i_1 \le i_2 \le ... \le i_k(1\le{k}\le{n}) i1​≤i2​≤...≤ik​(1≤k≤n)使得 a i 1 a n d a i 2 a n d . . . a n d a i k = 0 a_{i_1}\mathrm{\ and\ }a_{i_2}\mathrm{\ and\ }...\mathrm{\ and}\ a_{i_k}=0 ai1​​ and ai2​​ and ... and aik​​=0

求方案数模 1 0 9 + 7 10^9+7 109+7 。

也就是从 { a i } \{a_i\} {ai​} 里面选出一个非空子集使这些数按位与起来为 0 0 0.


S o l u t i o n \mathrm{Solution} Solution

前置芝士: 求 n n n个数中,任意 i i i 有几个数满足 a i a n d i = i a_i\ \mathrm{and\ } i=i ai​ and i=i。

考虑状压: f i ∑ j ∉ i f i + 2 j f_i\sum _{j∉i}f_{i+2^j} fi​j∈/​i∑​fi+2j​

这样我们发现会有重复,考虑为什么会重复。

那么怎么办呢?首先想到的容斥,即:加上新增 1 1 1 的,减去新增 2 2 2 的…

但是我们神奇的发现将 i i i 和 j j j 的枚举顺序调换一下,就神奇的不重复了。

因此我们得到了一个做状压计数的结论:

  • 若某一个数想要求得以它为子集的数的所有贡献,我们只需要调换枚举顺序,累计每一次新增 1 1 1 的贡献即可。

回到正题,那么这题运用上述结论就十分好解决了。

我们设 f i f_i fi​ 表示and值为 i i i 的答案,我们发现十分难搞。但是令 f i f_i fi​表示and值子集为 i i i 的方案数,我们发现我们可以用 f i f_i fi​ 减去以 i i i 的贡献即为正确答案。

类比上面的前置芝士,我们发现我们只要将加号改成减号就可以得到答案。

那么我们才能得到 f i f_i fi​ 呢,我们发现只要有 n n n 个数的子集存在 i i i,答案即为: 2 n − 1 2^n-1 2n−1

因此我们先令上述统计个数一遍,在变换成方案数以后再相减一遍即可。


C o d e \mathrm{Code} Code

#include <bits/stdc++.h>
#define int long longusing namespace std;
const int N = 3e6;
const int P = 1e9 + 7;int n, S;
int f[N];int read(void)
{int s = 0, w = 0; char c = getchar();while (!isdigit(c)) w |= c == '-', c = getchar();while (isdigit(c)) s = s*10+c-48, c = getchar();return w ? -s : s;
}int power(int a, int b) {int res = 1;while (b > 0) {if (b & 1) res = res * a % P;a = a * a % P, b >>= 1;}return res;
}void DP(int x)
{for (int j=0;j<=19;++j){for (int i=S-1;i>=0;--i)if (((i >> j) & 1) == 0) f[i] = (f[i] + f[i | 1 << j] * x) % P;}return;
}signed main(void)
{n = read(), S = (1 << 20) - 1;for (int i=1;i<=n;++i) f[read()] ++;DP(1);for (int i=0;i<=S;++i) f[i] = power(2, f[i]) - 1;DP(-1); cout << (f[0] + P) % P << endl;return 0;
}

『容斥·状压』CF449D Jzzhu and Numbers相关推荐

  1. [容斥 状压DP] HDU4997. Biconnected

    令 fSf_S 表示点集 SS 的答案,gSg_S 表示点集 SS 的连通图个数 那么 gSg_S 可以通过枚举与编号最小的点联通的点集求出来 fS=gS−∑T∈SgT×MT,S−Tf_S=g_S-\ ...

  2. [容斥 状压DP 树形DP] BZOJ 4455 [Zjoi2016]小星星 UOJ #185 【ZJOI2016】小星星

    杜老师说的哦 据说有人n*3^n卡过去 ? UOJ上需要卡常哦 #include<cstdio> #include<cstdlib> #include<algorithm ...

  3. cf449D. Jzzhu and Numbers(容斥原理 高维前缀和)

    题意 题目链接 给出\(n\)个数,问任意选几个数,它们\(\&\)起来等于\(0\)的方案数 Sol 正解居然是容斥原理Orz,然而本蒟蒻完全想不到.. 考虑每一种方案 答案=任意一种方案 ...

  4. [CQOI2012] 局部极小值(状压DP + 容斥 + 搜索)

    problem luogu-P3160 solution 这么小的数据范围,非暴力不状压.暴力 O(28!)O(28!)O(28!) 呵呵呵可以拉走了. 我们不妨从小到大填数字,这样如果局部极小值点还 ...

  5. P3160:局部极小值(容斥、状压)

    解析 又是一道我不会的容斥题 qwq 本题的一个关键性质:答案有解时,极小值不超过8个 所以可以对其进行状压 考虑从小到大填数 那么在极小值填完之前,它的八连通必然是不能填的 设计dpi,sdp_{i ...

  6. Wannafly挑战赛19:C. 多彩的树(状压+容斥)

    链接:https://www.nowcoder.com/acm/contest/131/C 来源:牛客网 题目描述 有一棵树包含 N 个节点,节点编号从 1 到 N.节点总共有 K 种颜色,颜色编号从 ...

  7. BZOJ 2560: 串珠子 (状压DP+枚举子集补集+容斥)

    (Noip提高组及以下),有意者请联系Lydsy2012@163.com,仅限教师及家长用户. 2560: 串珠子 Time Limit: 10 Sec Memory Limit: 128 MB Su ...

  8. 20200515省选模拟赛B、幻化成风(毒瘤容斥题+构造容斥系数+生成函数+hash状压DP+Trie树优化背包)

    题解 花了一上午+一中午终于把这道题A了 首先,我们要求的是bi互不相同的合法方案数 我们可以枚举一个a的集合S,来强制里面的b全部都相同,然后其它的随便放 由于这个题的n的约数非常多,我们可以把它质 ...

  9. Codeforces Round #257 (Div. 1) D. Jzzhu and Numbers 高维前缀和 + 容斥

    传送门 文章目录 题意: 思路: 题意: 思路: 完全想不到容斥啊,看了半天也没看懂渍渍渍. 定义f[i]f[i]f[i]表示iii的超集个数,那么选择的方案就是2f[i]−12^{f[i]}-12f ...

最新文章

  1. android 过度绘制
  2. C语言的补码表示和unsigned及signed的转换
  3. 通过webbrowser实现js与winform的相互调用
  4. Pytest高级进阶之Fixture
  5. linux 分割pdf,PDFBox分割PDF文档
  6. CF962E Byteland, Berland and Disputed Cities
  7. nodejs创建http服务器
  8. 迅捷pdf转换器(文件格式转换器)
  9. Windows 10 让所有程序默认为“以管理员身份运行”并且取消“确认”按钮
  10. 美国交通信号配时实践经验
  11. ipad协议更新非常稳定
  12. 【网站】八大极品桌面壁纸网站,惊艳
  13. LOL英雄联盟打不了文字,打字就一闪一闪的,英文可以,解决方式
  14. 好系统帮你恢复win7经典开机画面
  15. 断点续传续播的大概原理
  16. AutoMapper Project To OrderBy Skip Take 正确写法
  17. 04 分布式文件系统以及MapReduce入门程序
  18. 《PHASEN:A Phase and Harmonics-Aware Speech Enhancement Network》Pytorch代码学习
  19. php 多个一维数组合拼成二维数组的方法
  20. MICCAI 论文投稿须知翻译

热门文章

  1. 企业财务制度二--(二)负债类科目 2131 预收账款(转载)
  2. 带宽共享跟独享有什么区别
  3. 将绿色计算进行到底,蚂蚁集团四大硬核黑科技全公开
  4. PIP换元,暴力换元,没有多余操作。
  5. 对于云原生时代的后端业务开发和项目系统学习,选Go Or Java?
  6. pyautogui.locateCenterOnScreen 返回NoneType错误
  7. android上用NFC读卡
  8. 【网络】网络基础套接字编程详解
  9. jenkins安装报错
  10. js静态页面间的传值