Soluton
令 \(v=2^{20}-1\)。
異或和的次冪非常不可做,考慮求出異或和為 \(i\) 的方案數 \(ct_i\),答案即為 \(\sum_{i=0}^{v}ct_i\times i^k\)。
考慮集合冪級數。設 \(x,y\),它們的乘法分別定義為 \(x^a\cdot x^b=x^{a\text{ xor }b}\),\(y^a\cdot y^b=y^{(a+b)\bmod m}\)。那麼 \(ct_t\) 就是:
加入 \(\text{FWT}\),簡易說明一下 \(\text{FWT}\):
原來那個式子變成:
由於 \(\text{FWT}\) 的線性性,把 \([y^0]\) 放進去:
外面的 \(\text{IFWT}\) 最後做一下就好了,不用管它,我們來觀察 \(\prod_{j=1}^{n}[x^i]\text{FWT}(1+yx^{p})\) 有沒有啥性質。
容易發現:
那麼我們設 \(\prod_{j=1}^{n}[x^i]\text{FWT}(1+yx^{A_j}))=(1+y)^{a_i}(1-y)^{b_i}\)。這個 \(a_i,b_i\) 怎麼求呢?
可以發現設 \(f=\sum x^i\sum_{j=1}^{n}[A_j=i]\),\(a_i-b_i\) 就是 \([x^i]\text{FWT}(f)\)。
我們再把式子拿回來:
\((1+y)^{a_i},(1-y)^{b_i}\) 都可以 \(\mathcal{O}(nm)\) 預處理展開後的係數。而 \((a_i,b_i)\) 總共只有 \(n+1\) 種,每種 \((1+y)^{a_i}(1-y)^{b_i}\) 的 \(y^0\) 項係數可以 \(\mathcal{O}(m)\) 求出。這部分預處理總複雜度 \(\mathcal{O}(nm)\)。
綜上,我們在 \(\mathcal{O}(nm)\) 時間內處理出了 \(\sum x^i\cdot[y^0]((1+y)^{a_i}(1-y)^{b_i}\),最後 \(\text{IFWT}\) 一下即可得出答案。
求 \(i^k\) 部分拿個線性篩可以變成 \(\frac{v\log k}{\log v}\),不過沒啥必要。
時間複雜度 \(\mathcal{O}(nm+v\log v+v\log k)\)。
Summary
主要思路:
- 寫出式子
- 化簡 \(\prod_{j=1}^{n}[x^i]\text{FWT}(1+yx^{A_j}))\)。
- 直接做即可。
Code
const int N = 2e5 + 5, M = 105, K = 1.1e6 + 5, mod = 998244353;
typedef Mint<mod> MI;
int n, m, k, x; MI rs, f[K], A[N][M], B[N][M], coe[N];
void fwt(MI* f, int n, int op) {
MI inv2 = (MI)1 / 2;
REP(i, 0, n - 1) REP(j, 0, (1 << n) - 1) {
if (j >> i & 1) continue;
MI x = f[j], y = f[j ^ 1 << i];
f[j] = x + y, f[j ^ 1 << i] = x - y;
if (op < 0) f[j] *= inv2, f[j ^ 1 << i] *= inv2;
}
}
int main() {
cin >> n >> m >> k;
REP(i, 1, n) cin >> x, f[x] += 1;
A[0][0] = B[0][0] = 1;
REP(i, 0, n - 1) REP(j, 0, m - 1) {
A[i + 1][j] += A[i][j];
A[i + 1][(j + 1) % m] += A[i][j];
B[i + 1][j] += B[i][j];
B[i + 1][(j + 1) % m] -= B[i][j];
}
REP(i, 0, n) REP(j, 0, m - 1)
coe[i] += A[i][j] * B[n - i][(m - j) % m];
fwt(f, 20, 1);
REP(i, 0, (1 << 20) - 1)
f[i] = coe[(f[i] + n).x / 2];
fwt(f, 20, -1);
REP(i, 0, (1 << 20) - 1)
rs += f[i] * qpow((MI)i, k);
cout << rs << '\n';
return 0;
}
``