ARC146C
若 S 合法,则首先这个条件显然等同于没有一个 S 的非空子集满足元素个数为偶数且元素异或和为 0。
对于一个满足条件的 S,我们能加入哪些非负数使得条件仍然满足呢?
设 T 是 S 的一个元素个数为奇数的子集,令 x 为 T 中元素异或和。那么显然,x 是不能被加入 S 中的。
然后接下来是最关键的性质,对于一个合法的 S,如果 T,U 均是 S 的一个元素个数为奇数的子集,且 T,U 不同,那么 T,U 中元素异或和也不同。
证明:若两者元素异或和相同,那么这样一个集合(由只存在于 T 中的元素和只存在于 U 中的元素组成的集合)必然满足元素个数为偶数且异或和为 0。而这个集合显然是 S 的非空子集,这与 S 合法矛盾。
因此,对于所有合法的 S,能加进 S 且依然合法的非负元素数量为 2N− S 的元素个数为奇数的非空子集的数量。
于是可以 DP 了。
设 fi 表示元素数量为 i 的合法 S 数量。
初值为 f0=1,f1=2N。
转移为 fi=fi−1×(2N−2i−2)i(i≥2)。
除以 i 是因为集合是无序的。
而且通过上述转移,可以发现不存在元素个数超过 N+1 的合法的集合。
时间复杂度为 O(N) 或 O(NlogN),取决是否预处理逆元。
Code:
#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef long long ll;
const int N = 100005, mod = 998244353;
int n;
int ans;
int qpow(int x, int y) {
int res = 1;
while (y) {
if (y & 1) res = res * x % mod;
x = x * x % mod;
y >>= 1;
}
return res;
}
int inv(int x) { return qpow(x, mod - 2); }
signed main() {
scanf("%lld", &n);
ans = 1; ll now = qpow(2, n);
ans = (ans + now) % mod;
for (int i = 2; i <= n + 1; ++i) {
now = now * (qpow(2, n) - qpow(2, i - 2) + mod) % mod * inv(i) % mod;
ans = (ans + now) % mod;
}
printf("%lld", ans);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话