鲜花:几种快速计算多个少项式异或卷积的算法
我也不知道我写了个啥标题,反正就很厉害就是了。
一
给定常数 \(a,b,c\),给定 \(n\) 个二元组 \((x_i,y_i)\),已知 \(f\) 满足 \(f_{0,0}=1\) 且 \(f_{i,j}=af_{i-1,j}+bf_{i-1,j\oplus x_i}+cf_{i-1,j\oplus y_i}\),求 \(f_{n,*}\) 的每一项系数。
\(1\le n\le 10^7,0\le x_i,y_i\le 2^{20}\)。
首先发现存在 \(O(nm)\) 做法。
将每个二元组视作一个序列 \(h\),满足 \(h_0=a,h_x=b,h_y=c\),那么每次 DP 相当于和 \(h\) 序列做 xor 卷积。每次求 \(\text{fwt}(h)\) 可以做到 \(O(nm\log m)\),比暴力劣一点。
因为 \(h\) 只有 \(O(1)\) 个位置有值,考察 \(\text{fwt}(h)\) 的形式,其只存在四种本质不同的取值:\(a+b+c,a+b-c,a-b+c,a-b-c\)。考虑每一个位置,那么设这四种值在 \(n\) 个 FWT 序列中出现次数分别为 \(p_1,p_2,p_3,p_4\),那么我们就能得知这个位置在进行 \(n\) 次卷积后的值为 \((a+b+c)^{p_1}(a+b-c)^{p_2}(a-b+c)^{p_3}(a-b-c)^{p_4}\)。
现在问题转化为对于每个位置,求 \(p_1,p_2,p_3,p_4\) 的值。我们计算维护三个序列 \(f_1,f_2,f_3\),对于 \(n\) 个二元组,我们在 \(f_1\) 的 \(x\) 位置 \(+1\),在 \(f_2\) 的 \(y\) 位置 \(+1\),在 \(f_3\) 的 \(x\oplus y\) 位置 \(+1\),记这三个序列 FWT 之后某个位置的值分别为 \(c_1,c_2,c_3\),那么我们就能知道这个位置的 \(p_1,p_2,p_3,p_4\) 满足:
那么可以解出 \(p_1,p_2,p_3,p_4\) 的值,得到对应序列之后 IFWT 回去即可求出 \(f_n\)。
复杂度 \(O(n+m\log m)\),实在是神仙。
二
给定 \(n\) 个三元组 \((a_i,b_i,x_i)\),已知 \(f\) 满足 \(f_{0,0}=1\) 且 \(f_{i,j}=a_if_{i-1,j}+b_if_{i-1,j\oplus x_i}\),求 \(f_{n,*}\) 的每一项系数。
\(0\le n,m\le 2^{20}\)。
其实也能做五元组的,但是我太懒了不想推了 /kel。
考虑延续上面的思路,我们快进到 FWT 部分。
我们要求:
于是我们算出来 \(p_1,p_2\) 直接做 FWT 再 EXP 即可求出答案。
复杂度 \(O(n \log m+m\log m)\)。
两个题的核心思想在于化 \(\prod\) 为 \(\sum\),然后利用 FWT 的线性性统一处理。
upd:上面的东西在 HN 省集被爆了,现在我们来提供一种简单的做法。
首先我们认为 \(a,b\) 是互不相同的,因为相同的我们可以合并处理。
考虑在 trie 上 DP,设 \(f_{x,s,0/1}\) 表示考虑 \(x\) 子树内的点,选的点异或和为 \(s\),子树内选的点的个数是奇偶的方案数。转移就是做异或卷积,直接卷可以做到 \(O(n\log^2 n)\) 的复杂度。
考虑优化,一个想法是我们直接维护 DP 数组的 FWT 值,这样每次做子集卷积的话相当于对位相乘,唯一困难的在于我们有时候需要倍长数组,在数组前补相同数量的 \(0\),或者在数组后补相同数量的 \(0\),这个对于 FWT 数组的影响相当于将 FWT 数组倍长然后将 FWT 数组的后半部分取相反数。复杂度变为 \(O(n \log n)\)。

浙公网安备 33010602011771号