设 \(f_{x,0,i}\) 表示 \(x\) 子树中,所有包含 \(x\) 且异或和为 \(i\) 的连通块数量,\(f_{x,1,i}\) 表示 \(x\) 子树中异或和为 \(i\) 的连通块数量。显然,有公式
\[f_{x,1,i}=f_{x,0,i}+\sum\limits_{y\in\text{subtree}_x}f_{y,1,i}
\]
现在考虑 \(f_{x,0,i}\) 的转移。假如我们要合并 \(x\) 与某个儿子 \(y\) 的DP数组,则显然有公式
\[f_{x,0,i}=\sum\limits_{j\operatorname{xor}k=i}f'_{x,0,j}\times(f_{y,0,k}+[k=0])
\]
其中 \(f'\) 是老的 \(f\) 数组。
发现这是异或卷积形式,可以FWT优化。
但是我们发现,因为DP过程中全程要么在卷积,要么在做加法,对FWT后的数组作也是一样的。因此我们重新修改定义,将 \(f\) 数组全数修改为FWT后的数组。又因为 \(z^0\) 这个函数在FWT后会得到 \(\sum\limits_{i=0}^mz^i\),因此转移式变更为
\[f_{x,1,i}=f_{x,0,i}+\sum\limits_{y\in\text{subtree}_x}f_{y,1,i}
\]
\[f_{x,0,i}=f'_{x,0,j}\times(f_{y,0,k}+1)
\]
直接硬DP,单次复杂度 \(O(nm)\)。
现在考虑轻重链剖分。设 \(g\) 表示仅考虑轻儿子时的答案。若只考虑 \(x\) 的一个重儿子 \(y\),则有
\[f_{x,0}=g_{x,0}\times(f_{y,0}+1)=g_{x,0}f_{y,0}+g_{x,0}
\]
\[f_{x,1}=f_{x,0}+g_{x,1}+f_{y,1}=g_{x,0}f_{y,0}+g_{x,0}+g_{x,1}+f_{y,1}
\]
当然,这里的所有东西都是函数,连上面的 \(1\) 都不例外,指的是元素全为 \(1\) 的函数。
同时,要留心一点常规 \(g\) 的转移:
\[g_{x,0}=\text{FWT}(z^{a_x})\prod\limits_{y\in\text{lightson}_x}(f_{y,0}+1)
\]
\[g_{x,1}=\sum\limits_{y\in\text{lightson}_x}f_{y,1}
\]
需要注意的是,叶节点的 \(g\) 数组应直接是其 \(f\) 数组,故对于叶子节点,有 \(g_{x,0}=g_{y,0}=\text{FWT}(z^{a_x})\)。
我们可以列出转移矩阵来:
\[\begin{bmatrix}f_{y,0}\\f_{y,1}\\1\end{bmatrix}\begin{bmatrix}g_{x,0}&g_{x,0}&0\\0&1&0\\g_{x,0}&g_{x,0}+g_{x,1}&1\end{bmatrix}=\begin{bmatrix}f_{x,0}\\f_{x,1}\\1\end{bmatrix}
\]
\(3\times3\) 矩阵就有着 \(3^3\) 的常数,不好玩。但是,当我们计算两个上述矩阵的积后
\[\begin{bmatrix}a_1&b_1&0\\0&1&0\\c_1&d_1&1\end{bmatrix}\begin{bmatrix}a_2&b_2&0\\0&1&0\\c_2&d_2&1\end{bmatrix}=\begin{bmatrix}a_1a_2&b_1+a_1b_2&0\\0&1&0\\a_2c_1+c_2&b_2c_1+d_1+d_2&1\end{bmatrix}
\]
发现矩阵的积不会影响其余位置的取值。
因此我们考虑只维护 \(a,b,c,d\) 四个位置的值,即可压缩矩阵为 \(2\times2\)。
于是现在的转移矩阵就压缩为
\[\begin{bmatrix}a_1&b_1\\c_1&d_1\end{bmatrix}\begin{bmatrix}a_2&b_2\\c_2&d_2\end{bmatrix}=\begin{bmatrix}a_1a_2&b_1+a_1b_2\\a_2c_1+c_2&b_2c_1+d_1+d_2\end{bmatrix}
\]
同时,其存在单位元
\[\begin{bmatrix}1&0\\0&0\end{bmatrix}
\]
我们同时还要支持从链顶父亲的 \(g\) 数组中删掉一个 \(f\) 数组的操作。这样就需要支持除法。但是你不能保证FWT不会出现零。但我们可以维护每个位置的非零数之积是什么,再维护每个位置出现了多少零,这样分开处理,即可支持除法。
代码先咕着