題解:AT_abc367_g [ABC367G] Sum of (XOR^K or 0)

喵仔牛奶發表於2024-09-03

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\) 就是:

\[[x^ty^0]\prod_{i=1}^{n}(1+yx^{A_i}) \]

加入 \(\text{FWT}\),簡易說明一下 \(\text{FWT}\)

\[[x^i]\text{FWT}(A)=\sum_j(-1)^{\text{popcount(i\text{ and }j)}}[x^j]A \]

原來那個式子變成:

\[[x^ty^0]\text{IFWT}(\sum x^i\prod_{j=1}^{n}[x^i]\text{FWT}(1+yx^{A_j})) \]

由於 \(\text{FWT}\) 的線性性,把 \([y^0]\) 放進去:

\[[x^t]\text{IFWT}(\sum x^i[y^0]\prod_{j=1}^{n}[x^i]\text{FWT}(1+yx^{A_j})) \]

外面的 \(\text{IFWT}\) 最後做一下就好了,不用管它,我們來觀察 \(\prod_{j=1}^{n}[x^i]\text{FWT}(1+yx^{p})\) 有沒有啥性質。

容易發現:

\[[x^i]\text{FWT}(1+yx^{p}))=\begin{cases}1+y&\text{popcount}(i\text{ and }p)\equiv 0\pmod 2\\1-y&\text{popcount}(i\text{ and }p)\equiv 1\pmod 2\end{cases} \]

那麼我們設 \(\prod_{j=1}^{n}[x^i]\text{FWT}(1+yx^{A_j}))=(1+y)^{a_i}(1-y)^{b_i}\)。這個 \(a_i,b_i\) 怎麼求呢?

\[\begin{cases} a_i+b_i=n,\\ a_i-b_i=\sum_{i=1}^{n}(-1)^{\text{popcount}(i\text{ and }A_i)} \end{cases} \]

可以發現設 \(f=\sum x^i\sum_{j=1}^{n}[A_j=i]\)\(a_i-b_i\) 就是 \([x^i]\text{FWT}(f)\)

我們再把式子拿回來:

\[[x^t]\text{IFWT}(\sum x^i[y^0](1+y)^{a_i}(1-y)^{b_i}) \]

\((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;
}
``

相關文章