Walsh–Hadamard 变换与旁的有机联系
感谢 @tiger0133 提供的优质学习博客以及耐心解答。
感谢 @crashed ,@Rainybunny 为促使我理解提供的大力支持。
感谢太阳神 @Tiw_Air_OAO 为撰写本文提供的精神支持 现在这句话不应该有删除线了!
实际上你可以发现这是各类大仙的博客拼接!
不知道贴什么标签。
首先要给出一个宏伟壮观的 FWT 全名来钓鱼,然后再沿用太阳神的博客名称进行一个敬的致。
定义 \(\displaystyle [x^i]\operatorname{FWT}(A) = \sum_{j=0}^{n-1} a_j f(i,j)\)。
借用 FFT 的想法,我们想构造正确的变换 \(f(i,j)\) 使得 \([x^i]\operatorname{FWT}(A)[x^i]\operatorname{FWT}(B) = [x^i]\operatorname{FWT}(A \cdot B)\)。其中 \(\cdot\) 指位运算卷积,即 \(\displaystyle [x^i](A \cdot B) = \sum_{j \oplus k = i} [x^j]A[x^k]B\),其中 \(\oplus\) 指二元位运算。
对等式左边右边分别考虑:
注意到下面式子中那个 \(t\) 的枚举显得多余而无用,改成直接枚举 \(j,k\),发现和上面的式子几乎相同。那么要满足变换 \(f(i,j \oplus k) = f(i,j)f(i,k)\)。
不难发现 \(f\) 可以拆位处理,那么 \(\displaystyle f(i,j) = \prod_{k=0} f(i_k,j_k)\),其中 \(i_k\) 表示 \(i\) 在二进制表示下的第 \(k\) 高位,从 \(0\) 开始编号。
不妨继续采用 DFT 的思路,将 \([x^i]\operatorname{FWT}(A)\) 的计算拆成两部分:
拆出一个位,例如最高位。
注意到这个过程只跟我们拆出来的一个位有关,剩下的是子问题,相当于把整个序列劈成两半(假设把序列补成了 \(2^p\))。可以递归处理。
考察 \([x^i]\operatorname{FWT}(A)\) 和 \([x^{i+2^c}]\operatorname{FWT}(A)\)(\(i \otimes 2^c = i+2^c\),其中 \(\otimes\) 为二进制下的异或运算)在拆出 \(2^c\) 这一位下的结果:
写成矩阵的转移形式:
同时继续用 IDFT 的思路,IFWT 的过程就是:
那么剩下的工作是构造。随机找一个实例:
OR 卷积
真值表:\(\begin{bmatrix} 0 & 1 \\ 1 & 1\end{bmatrix}\)。
列出若干方程:
(这么写的原因是直接 OR 卷积每一位上并没有区别。有些题可能出现每一位的规则不同,特殊情况特殊考虑。)
那么能求出两组合法解 \(f(0)=1,f(1)=1\) 和 \(f(0)=1,f(1)=0\)。可以列出两个合法的矩阵(\(\begin{bmatrix} 1 & 1 \\ 1 & 0 \end{bmatrix}, \begin{bmatrix} 1 & 0 \\ 1 & 1 \end{bmatrix}\))(不难发现找到合法矩阵要让 \(f\) 有 \(2\) 组合法解,因为这是二进制位运算)。
此时 OR 卷积存在实际意义,可以对照实际意义理解两个矩阵的合法性(前者相当于 \(i\) 的补集的子集和,后者相当于 \(i\) 的子集和)。
求逆是 trivial 的工作,像这种一般可以手推,不会的可以看这个。
(当然有些卷积一眼过去是没有实际意义的,比如 XOR 卷积之类……吗?)
IMPLY 卷积
我不知道为啥叫这个。
真值表:\(\begin{bmatrix} 1 & 1 \\ 0 & 1\end{bmatrix}\)。
因为这里 \(0 \oplus 1 \neq 1 \oplus 0\),我们不好直接搞。
注意到,(~i | j) = t
,在一开始可以将 \(A\) 中 i
和 ~i
上的数交换,然后问题就变成了或卷积。
开摆卷积
真值表:\(\begin{bmatrix} 0 & 0 \\ 0 & 0\end{bmatrix}\)。
不管你传什么我都是 \(0\)。
这个东西就非常谔谔,直接搞就完事儿了。
同理可以找到什么开卷卷积,反正都差不多。
知道这三个情况就可以处理掉所有二进制位运算了。
随机例题:Codeforces Gym 102956A。当然我推荐是没必要写。
子集卷积,本质上是通过限制二进制表示下 \(1\) 的个数来保证转移的正确性,比较 naive 可以看板子。
先来整一个小 intro:给定序列 \(a,b\),求 \(a * b\)。其中 \(\displaystyle (a * b)_i = \sum_{\min\{j,k\}=i}a_jb_k\)。
显然这是一个 \(\min\) 卷积。构造变换 \(A_i = \sum_{i \leq j} a_j\),对 \(b,c\) 用同样的做法处理,可以知道 \(C_i = A_iB_i\)。求逆变换就是 \(c_i=C_i-C_{i+1}\)。
其本质是后缀和以及对应的差分。
同理我们可以推广到二维,简单分析之后发现其本质是二维后缀和及其对应的差分。
那么考虑推广到更高维,不难发现就是高维前缀和及其对应的差分。不难发现 AND 卷积本质就是这个。
联想到莫比乌斯反演。考虑 \(\gcd\) 的结构:\(\displaystyle a = \prod p_i^{u_i} , b = \prod p_i^{v_i}\),可知 \(\displaystyle \gcd(a,b)= \prod p_i^{\min\{u_i,v_i\}}\)。
不难发现 AND 卷积也是对应位取 \(\min\)。容易发现其中的有机联系。两者本质上都是对应位上做高维后缀和及差分。
再考虑 XOR 卷积。先考察 XOR 卷积的转移矩阵及其逆矩阵(一组):
这个 \(0.5\) 实则蹊跷。实际上十六种真值表中,只有和异或有关的出现了小数。并且发现 \(0.5A = A^{-1}\)。
先不考虑这些,不妨对一个序列做两次 FWT 的过程(不进行 IFWT)。对于一个 \(m=2^2\) 的数列,数列上的每一个数是答案的 \(4\) 倍;\(m=2^3\),数列上的每一个数是答案的 \(8\) 倍……不难发现做两次 FWT,会使答案是原来的 \(m\) 倍。
考虑这个 \(f(i,j)\),需要满足 \(f(i,j \oplus k) = f(i,j)f(i,k)\),在二进制异或下容易发现 \(f(i,(j + k) \bmod 2) = f(i,j)f(i,k)\)。这是一个类似于循环卷积的过程。看到这种东西,幂次可以直接取模,不难联想到单位根。思考这个 \(A\),是不是可以表示成 \(\begin{bmatrix} \omega_2^0 & \omega_2^0 \\ \omega_2^0 & \omega_2^1 \end{bmatrix}\);进一步,\(A^{-1} = \dfrac{1}{2}\begin{bmatrix} \omega_2^0 & \omega_2^0 \\ \omega_2^0 & \omega_2^{-1} \end{bmatrix}\)。
那么再考虑更高进制的异或卷积,比如 n-XOR 卷积。一样的考虑 \(f(i,(j+k) \bmod n) = f(i,j)f(i,k)\),那么显然可以知道存在合法的矩阵:
通过单位根反演可以证明 \(\{a_i\}\) 的正交性,可以证明其模长为 \(\sqrt n\)。
注意到 DFT 中,从系数表示到点值表示,我们乘上的实际上也是这个矩阵。我们也发现了 XOR 卷积和循环卷积的有机联系——XOR 卷积本质上是对每一位做 \(n\) 位的循环卷积。再回去考虑 XOR 卷积中的逆矩阵带上的系数 \(0.5 = \dfrac{1}{2}\),代表我们在乘上 \(A_2\) 的过程中,使答案变成了原来的 \(m=p^n\) 倍。当然这个倍数似乎也可以直接单位根反演推一推。
得到了太阳神的教导,知识增加了!
先考虑用 FFT 做多项式乘法的本质。根据上面的分析,可以指出其本质为循环卷积,即 \(F(x) = A(x)B(x) \bmod (x^n-1)\)。平常的题目中我们可以假设 \(n\) 非常大,这样就不会发生取模。
因为我们已经知道 XOR 卷积是按某一种确定的顺序,对每一位进行循环卷积(顺序可以任意),相当于在 \(\bmod (x_1^2-1) \bmod (x_2^2-1) \cdots \bmod (x_n^2-1)\) 意义下做乘法。
这个时候我们可以开始考虑 XOR 卷积的“实际”意义。这个取模过程相当于,次数对 \(2\) 取模并放到对应的位置上,相当于循环卷积。考虑异或的过程,如果出现了两个 \(1\),我们可以直接消去。因此这种取模构造的合法性显而易见。
上面我们还发现了 AND(OR) 卷积与莫比乌斯反演之间的关联,现在我们想通过一些方法使二者统一。
先考虑 OR 卷积。给出一个结论,或卷积相当于在 \(\bmod (x_1^2-x_1) \bmod (x_2^2-x_2) \cdots \bmod (x_n^2-x_n)\) 意义下做乘法。
其意义与上面类似,只不过这里是指数为 \(0\) 就放在 \(0\),否则无论是什么都是放在 \(1\)。考虑或运算的过程,容易发现构造的合法性。
最后考虑 AND 卷积……放到 \(0\) 这个性质不太优秀。我们沿用 IMPLY 卷积的方法,假设我们要求的是 \(h = f * g\),那么先将 \(f,g\) 中所有 i
和 ~i
位置上的数交换,做一次或卷积到 \(h\),最后将 \(h\) 中所有 i
和 ~i
位置上的数交换。正确性来源于 ~((~i)|(~j))=i&j
。
可以思考 OR 卷积在这种解释下如何对应实际意义。
太阳神降下神谕,为我们指出了 EI 冬令营营员交流的一条明路。可惜我没有找到,下次再来 ×