ARC144C
经典结论,集合大小不超过 \(n+1\)。
考虑往一个当前满足条件的集合里面加元素。对于原集合里的任意一个大小为奇数的子集,它的异或和不能与当前加入元素相等。
而由于这个集合当前满足条件,因此它的任意一个大小为奇数的子集异或和均不同。
所以能加入的数字个数就是 \(2^n\) 减去该集合奇数子集数量。
dp 处理即可,注意转移时因为不考虑元素顺序需要除掉重复方案。
#include <cstdio>
const int mod = 998244353;
int pow2[200005], dp[200005];
int qpow(int a, int b) {
int ret = 1;
while (b) {
if (b & 1) ret = 1ll * ret * a % mod;
a = 1ll * a * a % mod, b >>= 1;
}
return ret;
}
int main() {
int n, ans = 0;
scanf("%d", &n);
pow2[0] = 1;
for (int i = 1; i <= n; ++ i) pow2[i] = 2ll * pow2[i - 1] % mod;
dp[0] = 1, dp[1] = pow2[n];
for (int i = 2; i <= n + 1; ++ i)
dp[i] = 1ll * dp[i - 1] * (pow2[n] - pow2[i - 2]) % mod * qpow(i, mod - 2) % mod;
for (int i = 0; i <= n + 1; ++ i) ans = (ans + dp[i]) % mod;
printf("%d", (ans + mod) % mod);
return 0;
}