考虑到这个最终的答案是 \(\oplus\),所以只需要考虑每种排列出现的次数的奇偶,如果为奇再计算贡献即可。
考虑什么情况下出现次数为奇。
令每个数出现的个数为 \(c_{1\sim n}\),方案数即为 \(\dbinom{k}{c_1, c_2, \cdots, c_n} = \prod_{i = 1}^n \dbinom{k - \sum\limits_{j = 1}^{i - 1} c_j}{c_i}\)。
如果 \(\bmod 2 = 1\) 那么就说明 \(\dbinom{k - \sum\limits_{j = 1}^{i - 1} c_j}{c_i}\bmod 2 = 1(1\le i\le n)\),由 \(\text{Lucas}\) 定理可以得到二进制意义下 \(c_i\subseteq (k - \sum\limits_{j = 1}^{i - 1} c_j)\)。
证明就是考虑拆二进制位,因为 \(\binom{0}{0} = \binom{1}{1} = \binom{1}{0} = 1, \binom{0}{1} = 0\),所以如果 \(\bmod 2 = 1\) 需要每一位都满足是前 \(3\) 种,也就是对应的子集关系。
那么整理一下就有 \(c_i\operatorname{bitand}c_j = 0(1\le i < j\le n), c_1\operatorname{bitor} c_2 \operatorname{bitor}\cdots \operatorname{bitor} c_n = k\)。
对于答案,可以考虑拆位,对每一位依次来考虑为 \(0\) 还是 \(1\)。
因为能发现值域 \(V\le 1000\),考虑直接 \(\text{DP}\),设 \(f_{w, i}\) 为只考虑到第 \(w\) 位,到这一位的和为 \(j\) 的方案数为奇还是偶。
那么转移分为两种,如果下一位 \(k\) 为 \(0\),就选不了数,就直接折半由 \(i\) 转移到 \(\lfloor\frac{i}{2}\rfloor\)。
否则这一位需要选一个 \(a_j\) 出来,就会转移到 \(\lfloor\frac{i}{2}\rfloor + a_j\)。
然后考虑算这一位是不是 \(1\)。
首先因为只考虑了前 \(w\) 位,若还有 \(c\) 位没考虑,那么方案数应该乘上 \(n^{c}\),当 \(n\bmod 2 = 0\land c > 0\) 时肯定为偶,直接跳过。
否则考虑找出 \(f_{w, i} = 1\) 的 \(i\),把这些 \(\oplus\) 起来,如果最低位为 \(1\) 就说明第 \(w\) 位为 \(1\)。
时间复杂度 \(O(nV\log k)\),\(V\) 为值域。
代码
#include<bits/stdc++.h>
using i64 = long long;
const int maxn = 1e3 + 10;
int n;
int a[maxn];
int is1[52];
int f[52][maxn * 2];
int main() {
i64 k; scanf("%d%lld", &n, &k);
for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
for (int i = 0; i < 50; i++) is1[i] = (k >> i & 1ll);
int c = 0;
for (int i = 0; i < 50; i++) c += is1[i];
i64 ans = 0;
if (is1[0]) {
for (int i = 1; i <= n; i++) f[0][a[i]] ^= 1;
} else f[0][0] = 1;
for (int i = 0; i < 50; i++) {
if (is1[i]) c--;
if ((n & 1) || ! c) {
int t = 0;
for (int j = 0; j <= 2000; j++) f[i][j] && (t ^= j);
if (t & 1) ans |= 1ll << i;
}
if (! is1[i + 1]) {
for (int j = 0; j <= 2000; j++) f[i + 1][j >> 1] ^= f[i][j];
} else {
for (int j = 0; j <= 2000; j++) for (int p = 1; p <= n; p++) f[i + 1][(j >> 1) + a[p]] ^= f[i][j];
}
}
printf("%lld\n", ans);
return 0;
}