快速沃尔什变换(FWT)

最近学了 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)=ij=kA(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(AB)=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 AB 表示多项式对应位置系数相乘。这样子我们就可以先求得变换后的多项式,然后 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=ij=iAj

感性理解就是算这个集合的所有子集的权值和。

可以发现

F W T ( A ∣ B ) = F W T ( A ) ⋅ F W T ( B ) FWT(A|B)=FWT(A)\cdot FWT(B) FWT(AB)=FWT(A)FWT(B)

满足要求。

然后我们看如何快速计算这个东西。

还是受 FFT 的启发,考虑分治算这个东西。假设当前多项式 A A A 次数为 2 n − 1 2^n-1 2n1 次,那么我们把他按最高位是 0 0 0 还是 1 1 1 分成两个次数为 2 n − 1 − 1 2^{n-1}-1 2n11 的多项式,叫做 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=iAj

表示取所有包含他的集合的权值和。

所以

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=iAjBk

首先我们假设异或变换为

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=0n1K(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=0n1K(x,i)(AxorB)i=j=0n1K(x,j)Ajk=0n1K(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=0n1K(x,i)jxork=iAjBk=j=0n1K(x,j)Ajk=0n1K(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=0n1k=0n1K(x,jxork)AjBk=j=0n1k=0n1K(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=0n1(1)i&jAj

只要尝试着在已知 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 理解。

作为一种工具,要熟练掌握并能在该用的地方用出来。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值