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;
}
posted @ 2022-08-21 15:40  zqs2020  阅读(39)  评论(0编辑  收藏  举报