考慮到這個最終的答案是 \(\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;
}