快速沃尔什变换
创建时间:2026-02-04
快速沃尔什变换
快速沃尔什变换(Fast Walsh–Hadamard Transform, FWT)是一种处理特殊的“多项式乘法”的算法。
以异或为例,现在给定 \(2\) 的正整数次幂 \(n\) 和长度为 \(n\) 的 0-index 序列 \(A = \{a_0, a_1, a_2, \cdots, a_{n-1}\}, B = \{b_0, b_1, b_2, \cdots, b_{n-1}\}\),试求序列 \(C = \{c_0, ,c_1, c_2, \cdots, c_{n-1}\}\),其中:
直接暴力做是 \(O(n^2)\) 的。考虑构造一种变换,将序列 \(A\) 变换为 \(\mathrm{FWT_{xor}}(A)\),使得
如果我们能快速求出 \(\mathrm{FWT_{xor}}(A), \mathrm{FWT_{xor}}(B)\),并由 \(\mathrm{FWT_{xor}}(C)\) 求出 \(C\),就能快速完成“多项式乘法”。
下面给出异或运算中 \(\mathrm{FWT_{xor}}\) 的定义:记
\(x \circ y = \text{popcount}(x \& y) \bmod 2\)
其中 \(\mathrm{popcount}(x)\) 为 \(x\) 在二进制下 \(1\) 的个数,\(\&\) 是按位与运算。
当 \(n \ge 2\) 时,构造 \(A_0 = \{a_0, a_1, a_2, \cdots, a_{\frac n 2 - 1}\}, A_1 = \{a_{\frac n 2}, a_{\frac n 2 + 1}, a_{\frac n 2 + 2}, \cdots, a_{n-1}\}\),记 \((X, Y)\) 为将序列 \(Y\) 拼接在 \(X\) 后面,根据数学推导:
故可以通过分治求出 \(\mathrm{FWT_{xor}}(A)\),进一步得到 \(\mathrm{FWT_{xor}}(B), \mathrm{FWT_{xor}}(C)\)。
令 \(\mathrm{IFWT_{xor}}(A)\) 为 \(\mathrm{FWT_{xor}}(A)\) 的逆运算。形式化的,设 \(A' = \mathrm{FWT_{xor}}(A)\),那么 \(\mathrm{IFWT_{xor}}(A') = A\)。由上面求 FWT 的式子解方程,得:
代码:
void fwt(int a[], int tot) {
for (int i = 1; i < tot; i *= 2)
for (int j = 0; j < tot; j += i * 2)
for (int k = j; k < j + i; k++) {
int x = a[k], y = a[k + i];
a[k] = (x + y) % mod;
a[k + i] = (x - y + mod) % mod;
}
}
void ifwt(int a[], int tot) {
for (int i = 1; i < tot; i *= 2)
for (int j = 0; j < tot; j += i * 2)
for (int k = j; k < j + i; k++) {
int x = a[k], y = a[k + i];
a[k] = 1ll * (x + y) * inv2 % mod;
a[k + i] = 1ll * (x - y + mod) * inv2 % mod;
}
}
类似的,我们有:
正确性证明
下面只证明异或运算下快速沃尔什变换的正确性。
首先易知,\((x \circ y) \oplus (x \circ z) = x \circ (y \oplus z)\),所以
事实上,我们可以构造矩阵 \(Mat\),使得 \(Mat_{i, j} Mat_{i, k} = Mat_{i, j \oplus k}\)。下面是满足条件的 \(Mat\):
求出其逆矩阵
发现与 FWT、IWFT 的过程中的系数完全吻合!
应用
容易证明,

浙公网安备 33010602011771号