专栏文章
CF449D Jzzhu and Numbers题解
题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mipduggv
- 此快照首次捕获于
- 2025/12/03 10:23 3 个月前
- 此快照最后确认于
- 2025/12/03 10:23 3 个月前
令 表示若干个数 & 起来的结果。
令 被 包含表示 x & y == y
直接设状态不好做。
于是转变思路。
令 表示 被 包含的所有 的方案数。
则答案可以由 容斥得到。
由于只关心 中 在二进制下有几个 ,所以简化成代码中的 , 表示有 个 。
问题转化成如何求 。 事实上只需求出 , 表示有多少个 被 包含。
。减一是因为要除去空集。
显然可以 求得。
代码如下 :
CPP#include <bits/stdc++.h>
using namespace std;
const int N = (1 << 20) + 100;
const int Mod = 1e9 + 7;
int n, res, a[N], f[N], g[N], _2[N];
inline void upd(int &x, int y) {
x += y;
if(x >= Mod) x -= Mod;
if(x < 0) x += Mod;
return;
}
signed main() {
ios :: sync_with_stdio(false);
cin.tie(0), cout.tie(0);
cin >> n;
_2[0] = 1;
for(int i = 1; i < (1 << 20); ++i) _2[i] = _2[i - 1] * 2 % Mod;
for(int i = 1; i <= n; ++i) cin >> a[i], ++f[a[i]];
for(int j = 0; j < 20; ++j)
for(int i = (1 << 20) - 1; ~i; --i)
if(i >> j & 1) upd(f[i ^ (1 << j)], f[i]);
for(int i = 0; i < (1 << 20); ++i) upd(g[__builtin_popcount(i)], _2[f[i]] - 1);
for(int i = 0; i < 20; ++i) {
if(i & 1) upd(res, -g[i]);
else upd(res, g[i]);
}
cout << res << '\n';
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...