最近学了 min-max 容斥,好像几乎每一道 min-max 容斥题都要用到 FWT 来辅助,所以顺便学一下 FWT。
概述
与 FFT 类似。
需要求的是
C ( k ) = ∑ i ⊕ j = k A ( i ) ∗ B ( j ) C(k)=\sum_{i\oplus j=k}A(i)*B(j) C(k)=i⊕j=k∑A(i)∗B(j)
其中 ⊕ \oplus ⊕ 可以指代位运算符号,例如按位和,按位或,按位异或。
实际上方法也非常类似。我们需要这样一个变换和他的逆变换
F W T ( A ⊕ B ) = F W T ( A ) ⋅ F W T ( B ) FWT(A\oplus B)=FWT(A)\cdot FWT(B) FWT(A⊕B)=FWT(A)⋅FWT(B)
I F W T ( F W T ( A ) ) = A IFWT(FWT(A))=A IFWT(FWT(A))=A
其中 A ⋅ B A \cdot B A⋅B 表示多项式对应位置系数相乘。这样子我们就可以先求得变换后的多项式,然后 O ( n ) O(n) O(n) 对应位置相乘,再变换回去。(废话)
或卷积
设
F W T ( A ) i = ∑ i ∣ j = i A j FWT(A)_i=\sum_{i|j=i}A_j FWT(A)i=i∣j=i∑Aj
感性理解就是算这个集合的所有子集的权值和。
可以发现
F W T ( A ∣ B ) = F W T ( A ) ⋅ F W T ( B ) FWT(A|B)=FWT(A)\cdot FWT(B) FWT(A∣B)=FWT(A)⋅FWT(B)
满足要求。
然后我们看如何快速计算这个东西。
还是受 FFT 的启发,考虑分治算这个东西。假设当前多项式 A A A 次数为 2 n − 1 2^n-1 2n−1 次,那么我们把他按最高位是 0 0 0 还是 1 1 1 分成两个次数为 2 n − 1 − 1 2^{n-1}-1 2n−1−1 的多项式,叫做 A 0 , A 1 A0,A1 A0,A1 。
然后观察可得
F W T ( A ) = ( F W T ( A 0 ) , F W T ( A 0 ) + F W T ( A 1 ) ) FWT(A)=(FWT(A0), FWT(A0)+FWT(A1)) FWT(A)=(FWT(A0),FWT(A0)+FWT(A1))
其中 ( A , B ) (A,B) (A,B) 表示两个多项式首尾相接。原因很简单,因为要取子集,所以这一位为 0 0 0 的一定包含于这一位为 1 1 1 的集合中。
然后就可以分治 O ( n log n ) O(n\log n) O(nlogn) 算了呀。
他的逆变换是这样的
I F W T ( A ) = ( I F W T ( A 0 ) , I F W T ( A 1 ) − I F W T ( A 0 ) ) IFWT(A)=(IFWT(A0),IFWT(A1)-IFWT(A0)) IFWT(A)=(IFWT(A0),IFWT(A1)−IFWT(A0))
感性理解起来也很方便,现在一个位置的数表示子集权值和,那我们还是一位一位考虑,把他的真子集全部都删掉就好了。
具体证明就不证了。并且这个东西比 FFT 还好写。
和卷积
一模一样。您可以将公式替换到上面的或卷积中,然后复读一遍。
F W T ( A ) i = ∑ i & j = i A j FWT(A)_i=\sum_{i\&j=i} A_j FWT(A)i=i&j=i∑Aj
表示取所有包含他的集合的权值和。
所以
F W T ( A ) = ( F W T ( A 0 ) + F W T ( A 1 ) , F W T ( A 1 ) ) FWT(A)=(FWT(A0)+FWT(A1), FWT(A1)) FWT(A)=(FWT(A0)+FWT(A1),FWT(A1))
I F W T ( A ) = ( F W T ( A 0 ) − F W T ( A 1 ) , F W T ( A 1 ) ) IFWT(A)=(FWT(A0)-FWT(A1), FWT(A1)) IFWT(A)=(FWT(A0)−FWT(A1),FWT(A1))
异或卷积
与上述两个不是很一样。稍微麻烦一点。这里我们用更为普适的方法来解决异或卷积的问题。
可以参考 这篇博客 。
异或卷积定义如下
( A x o r B ) i = ∑ j x o r k = i A j B k (A\;xor\;B)_i=\sum_{j\;xor\;k=i}A_jB_k (AxorB)i=jxork=i∑AjBk
首先我们假设异或变换为
F W T ( A ) i = ∑ j = 0 n − 1 K ( i , j ) A j FWT(A)_i=\sum_{j=0}^{n-1}K(i,j)A_j FWT(A)i=j=0∑n−1K(i,j)Aj
其中 K ( i , j ) K(i,j) K(i,j) 为关于 i , j i,j i,j 的函数。
然后考虑到
F W T ( A x o r B ) = F W T ( A ) ⋅ F W T ( B ) FWT(A \; xor \; B)=FWT(A)\cdot FWT(B) FWT(AxorB)=FWT(A)⋅FWT(B)
所以对于每一位 x x x 都有
∑ i = 0 n − 1 K ( x , i ) ( A x o r B ) i = ∑ j = 0 n − 1 K ( x , j ) A j ⋅ ∑ k = 0 n − 1 K ( x , k ) B k \sum_{i=0}^{n-1}K(x,i)(A \; xor \; B)_i=\sum_{j=0}^{n-1}K(x,j)A_j\cdot \sum_{k=0}^{n-1}K(x,k)B_k i=0∑n−1K(x,i)(AxorB)i=j=0∑n−1K(x,j)Aj⋅k=0∑n−1K(x,k)Bk
将最上面的定义带代入,得到
∑ i = 0 n − 1 K ( x , i ) ∑ j x o r k = i A j B k = ∑ j = 0 n − 1 K ( x , j ) A j ⋅ ∑ k = 0 n − 1 K ( x , k ) B k \sum_{i=0}^{n-1}K(x,i)\sum_{j\;xor\;k=i}A_jB_k=\sum_{j=0}^{n-1}K(x,j)A_j\cdot \sum_{k=0}^{n-1}K(x,k)B_k i=0∑n−1K(x,i)jxork=i∑AjBk=j=0∑n−1K(x,j)Aj⋅k=0∑n−1K(x,k)Bk
化简
∑ j = 0 n − 1 ∑ k = 0 n − 1 K ( x , j x o r k ) A j B k = ∑ j = 0 n − 1 ∑ k = 0 n − 1 K ( x , j ) K ( x , k ) A j B k \sum_{j=0}^{n-1}\sum_{k=0}^{n-1}K(x,j\;xor\;k)A_jB_k=\sum_{j=0}^{n-1}\sum_{k=0}^{n-1}K(x,j)K(x,k)A_jB_k j=0∑n−1k=0∑n−1K(x,jxork)AjBk=j=0∑n−1k=0∑n−1K(x,j)K(x,k)AjBk
所以我们发现
K ( x , j x o r k ) = K ( x , j ) K ( x , k ) K(x,j\;xor\;k)=K(x,j)K(x,k) K(x,jxork)=K(x,j)K(x,k)
只要系数满足这个就完全可以做 FWT 了。但是因为 IFWT 的需要,我们还要保证他可以反演,也就是说转移矩阵可逆。
所以对于异或卷积,根据人类智慧,我们发现系数可以这样设
K ( x , i ) = ( − 1 ) ∣ x & i ∣ K(x,i)=(-1)^{|x\& i|} K(x,i)=(−1)∣x&i∣
其中 ∣ A ∣ |A| ∣A∣ 表示集合大小,或者说一个二进制数中 1 1 1 的个数。
因为考虑异或对集合大小奇偶性的影响,发现两个集合异或之后他们集合大小的奇偶性也会异或起来。感性理解的话就把异或看成不进位的二进制加法就好。
然后因为
( x & i ) x o r ( x & j ) = x & ( i x o r j ) (x\&i)\;xor\;(x\& j)=x\&(i\;xor\;j) (x&i)xor(x&j)=x&(ixorj)
上面的式子对于集合大小的奇偶性也是一样的,所以系数
( − 1 ) ∣ x & ( i x o r j ) ∣ = ( − 1 ) ∣ x & i ∣ ⋅ ( − 1 ) ∣ x & j ∣ (-1)^{|x\&(i\;xor\;j)|}=(-1)^{|x\& i|}\cdot (-1)^{|x\& j|} (−1)∣x&(ixorj)∣=(−1)∣x&i∣⋅(−1)∣x&j∣
现在我们看看如何用分治来做异或卷积。
既然已经定义了
F W T ( A ) i = ∑ j = 0 n − 1 ( − 1 ) ∣ i & j ∣ A j FWT(A)_i=\sum_{j=0}^{n-1}(-1)^{|i\&j|}A_j FWT(A)i=j=0∑n−1(−1)∣i&j∣Aj
只要尝试着在已知 F W T ( A 0 ) , F W T ( A 1 ) FWT(A0),FWT(A1) FWT(A0),FWT(A1) 的情况下在每一个数前面加上 0 0 0 或者 1 1 1 再算一遍就好了,我们可以得到如下式子
F W T ( A ) = ( F W T ( A 0 ) + F W T ( A 1 ) , F W T ( A 0 ) − F W T ( A 1 ) ) FWT(A)=(FWT(A0)+FWT(A1),FWT(A0)-FWT(A1)) FWT(A)=(FWT(A0)+FWT(A1),FWT(A0)−FWT(A1))
I F W T ( A ) = ( I F W T ( A 0 ) + I F W T ( A 1 ) 2 , I F W T ( A 0 ) − I F W T ( A 1 ) 2 ) IFWT(A)=(\frac{IFWT(A0)+IFWT(A1)}{2},\frac{IFWT(A0)-IFWT(A1)}{2}) IFWT(A)=(2IFWT(A0)+IFWT(A1),2IFWT(A0)−IFWT(A1))
大功告成。
总结
和 FFT 非常类似,可以类比 FFT 理解。
作为一种工具,要熟练掌握并能在该用的地方用出来。