「学习笔记」FWT

「学习笔记」FWT

点击查看目录

理论基础

引入 \(\newcommand{FWT}[1]{\operatorname{FWT}(#1)}\)

常见的多项式卷积形式是 \(C[i] = \sum\limits_{j + k = i}A[j]B[k]\) .

类似地定义位运算卷积是形如 \(C[i] = \sum\limits_{j\oplus k = i}A[j]B[k]\) 的卷积,其中 \(\oplus\) 是一种位运算 .

FWT 可以以 \(O(n2^n)\) 的时间复杂度处理长度为 \(2^n\) 的位运算卷积 .

其过程同样可以类比 FFT,找到一种点值的映射后转化为点积 .

点值的构造

\(\FWT{A}\) 表示 \(A\) 经过变换后得到的幂级数 .

\(c(i, j)\) 表示系数,一个线性变换可以被表示为如下形式:

\[\FWT{A}[i] = \sum_{j = 0}^{2^n - 1} c(i, j) A[j] \]

现在所期望做的是构造出合适的 \(c(i, j)\) 满足点积运算的正确性 . 对于不同的位运算应有不同的构造方式,不过在此之前应该先将 \(c\) 的性质挖掘一些 .

首先展开点积式:

\[\begin{aligned} \FWT{C}[i] &= \FWT{A}[i]\FWT{B}[i]\\ \sum_{j = 0}^{2^n - 1} c(i, j) C[j] &= \left(\sum_{j = 0}^{2^n - 1} c(i, j) A[j]\right)\left(\sum_{j = 0}^{2^n - 1} c(i, j) B[j]\right)\\ \sum_{j = 0}^{2^n - 1} c(i, j) C[j] &= \sum_{j = 0}^{2^n - 1}\sum_{k = 0}^{2^n - 1} c(i, j)c(i, k)A[j]B[k]\\ \end{aligned} \]

代入位运算卷积的定义,应有以下等式:

\[\begin{aligned} \sum_{j = 0}^{2^n - 1} c(i, j)\sum\limits_{x\oplus y = j}A[x]B[y] &= \sum_{j = 0}^{2^n - 1}\sum_{k = 0}^{2^n - 1} c(i, j)c(i, k)A[j]B[k]\\ \sum_{j = 0}^{2^n - 1}\sum\limits_{x\oplus y = j}c(i, x\oplus y)A[x]B[y] &= \sum_{j = 0}^{2^n - 1}\sum_{k = 0}^{2^n - 1} c(i, j)c(i, k)A[j]B[k]\\ \sum_{x = 0}^{2^n - 1}\sum_{y = 0}^{2^n - 1}c(i, x\oplus y)A[x]B[y] &= \sum_{j = 0}^{2^n - 1}\sum_{k = 0}^{2^n - 1} c(i, j)c(i, k)A[j]B[k]\\ \end{aligned} \]

容易注意到当 \(c(i, j\oplus k) = c(i, j)c(i, k)\) 时等式一定成立,构造可以利用这个性质 .

另外注意到 \(\oplus\) 是位运算,那么总存在 \(j\oplus k = t\iff j_i\oplus k_i = t_i\)\(x_i\) 表示 \(x\) 二进制下的第 \(i\) 位),这提醒我们可以增加 \(c\) 的限制使得其可以拆位考虑进一步方便构造 . 一个简单的方式是钦定 \(c(i, j) = \prod c(i_k, j_k)\),这使得仅需要构造 \(i, j\in\{0, 1\}\) 时的 \(c(i, j)\) 即可得到所有 \(c(i, j)\) .

FWT 变换

现在的问题是,如何快速求出所有的 \(\FWT{A}[i]\),即 \(\sum_{j = 0}^{2^n - 1} c(i, j) A[j]\) .

分治考虑,可以按照 \(j\) 的最高位分为两部分,即:

\[\FWT{A}[i] = c(i_{n - 1}, 0)\sum_{j = 0}^{2^{n - 1} - 1} c(i', j') A[j] + c(i_{n - 1}, 1)\sum_{j = 2^{n - 1}}^{2^n - 1} c(i', j') A[j] \]

然后直接类似于 FFT 的方式枚举当前处理的长度 \(2^k\) 倍增处理即可.

具体的,假设当前已经求出了 \(A\) 左右两个子部分 \(A_0, A_1\) 的变换,那么有:

\[\FWT{A}_k[i] = c(i_{n - 1}, 0)\FWT{A_0}[i'] + c(i_{n - 1}, 1)\FWT{A_1}[i'] \]

不同位运算转移矩阵的构造

直接根据上文的性质对 \(2\times 2\) 矩阵列方程即可 .

不过注意我们还需定义 FWT 的逆变换,所以需要保证矩阵的逆存在 .

Or 卷积

\[\begin{cases} c(i, 0)c(i, 0) = c(i, 0)\\ c(i, 0)c(i, 1) = c(i, 1)\\ c(i, 1)c(i, 1) = c(i, 1)\\ \end{cases} \]

容易得到每行三组解,不过因为需要保证逆的存在仅有两组解:\(\begin{bmatrix}1&\ 1\\1&\ 0\end{bmatrix}\)\(\begin{bmatrix}1&\ 0\\1&\ 1\end{bmatrix}\) .

这里选用第二组解,其逆为 \(\begin{bmatrix}1\ &0\\-1\ &1\end{bmatrix}\) .

And 卷积

\[\begin{cases} c(i, 0)c(i, 0) = c(i, 0)\\ c(i, 0)c(i, 1) = c(i, 0)\\ c(i, 1)c(i, 1) = c(i, 1)\\ \end{cases} \]

保证逆的存在有与 or 相似的两组解:\(\begin{bmatrix}1&\ 1\\0&\ 1\end{bmatrix}\)\(\begin{bmatrix}0&\ 1\\1&\ 1\end{bmatrix}\) .

这里选用第一组解,其逆为 \(\begin{bmatrix}1&\ -1\\0&\ 1\end{bmatrix}\) .

Xor 卷积

\[\begin{cases} c(i, 0)c(i, 0) = c(i, 0)\\ c(i, 0)c(i, 1) = c(i, 1)\\ c(i, 1)c(i, 1) = c(i, 0)\\ \end{cases} \]

保证逆的存在的两组解:\(\begin{bmatrix}1&\ 1\\1&\ -1\end{bmatrix}\)\(\begin{bmatrix}1&\ -1\\1&\ 1\end{bmatrix}\) .

这里选用第一组解,其逆为 \(\begin{bmatrix}\dfrac{1}{2}&\ \dfrac{1}{2}\\\dfrac{1}{2}&\ -\dfrac{1}{2}\end{bmatrix}\) .

代码

namespace _FWT_ {
	const int inv2 = (P + 1) / 2;
	typedef std::array <std::array <int, 2>, 2> CMat;
	const CMat OR ({ 1, 0, 1, 1 }), IOR ({ 1, 0, P - 1, 1 });
	const CMat AND ({ 1, 1, 0, 1 }), IAND ({ 1, P - 1, 0, 1 });
	const CMat XOR ({ 1, 1, 1, P - 1 }), IXOR ({ inv2, inv2, inv2, P - inv2 });
	void FWT (int* F, int n, const CMat& C) {
		for (int len = 1; len < n; len <<= 1) {
			for (int p = 0; p < n; p += len * 2) {
				_for (i, p, p + len - 1) {
					ll w0 = F[i], w1 = F[i + len];
					F[i] = (C[0][0] * w0 + C[0][1] * w1) % P;
					F[i + len] = (C[1][0] * w0 + C[1][1] * w1) % P;
				}
			}
		}
		return;
	}
}

例题

线性基

私题放不出 .

Takahashi The Strongest

首先平移一下胜利条件变为三个值相等 . 使用三进制描述策略,题目所求的相当于进行一个卷积:

\[C[i] = \sum_{\exists t, i_t = j_t = k_t}A[j]B[k] \]

不过这样并没有办法定义位运算,因为 \(j, k\) 确定时结果却不确定 . 考虑设一个中间状态 \(0\) 表示可以这一位不限制输赢可以任意取,这使得原来的卷积转化为点积,和中间状态相关的转移可以使用 FWT(贡献累加到 \(0\) 上)和 IFWT(\(0\) 贡献出去)的方式做 .

另外注意到不限制输赢的方案会导致算重,需要做容斥 .

posted @ 2025-02-10 16:10  K8He  阅读(151)  评论(10)    收藏  举报