快速沃尔什变换(FWT)介绍

快速沃尔什变换(FWT)介绍

众所周知,FFT可以有效地解决如下的问题
A = ( a 1 , … , a n ) B = ( b 1 , . . . , b n ) C = ( c 1 , . . . , c n ) c k = ∑ i + j = k a i ∗ b j A=(a_1,\dots,a_n)\\ B=(b_1,...,b_n)\\ C=(c_1,...,c_n)\\ c_k=\sum_{i+j=k}a_i*b_j\\ A=(a1,,an)B=(b1,...,bn)C=(c1,...,cn)ck=i+j=kaibj
但事实上,把求和号里的条件里的“+”换成与、或、异或、同或也可以有 O ( n log ⁡ n ) O(n\log n) O(nlogn)时间复杂度的计算方法,这就是快速沃尔什变换(FWT)

鉴于与和或、异或和同或的处理方式比较相似,因此这里就重点分析或、异或这两种情况,另外两种只给结论

注:这里假设序列长度都是 2 k 2^k 2k(事实上必须补成这个样子)

或卷积

对于卷积来说,我们肯定希望最后变成元素积来进行运算,那么能够进行元素积的这个状态就是我们的目标,在FFT中这个目标状态是插值,而在或卷积中,我们要的目标状态是这样的
F W T o r ( A ) [ i ] = ∑ i ∣ j = i a j    ( ∗ ) FWT_{or}(A)[i]=\sum_{i|j=i}a_j\ \ (*) FWTor(A)[i]=ij=iaj  ()
事实上就是对于i来说 F W T o r ( A ) [ i ] FWT_{or}(A)[i] FWTor(A)[i]就是i的子集的对应位置的和(请记住这一点)

很容易看出
F W T o r ( C ) [ i ] = F W T o r ( A ) [ i ] ∗ F W T o r ( B ) [ i ] FWT_{or}(C)[i]=FWT_{or}(A)[i]*FWT_{or}(B)[i] FWTor(C)[i]=FWTor(A)[i]FWTor(B)[i]
(这里事实上没有证明这个C就是我们想要的C,但是这对我们目前的学习影响不太)

接下来就是如何去求 F W T o r ( A ) FWT_{or}(A) FWTor(A)

先给一个结论
F W T o r ( A + B ) = F W T o r ( A ) + F W T o r ( B ) FWT_{or}(A+B)=FWT_{or}(A)+FWT_{or}(B) FWTor(A+B)=FWTor(A)+FWTor(B)
这里的“+”是对应的元素相加

我们把A分成两半,记A0(前一半)和A1(后一半)然后我们有
F W T o r ( A ) = ( F W T o r ( A 0 ) , F W T o r ( A 0 + A 1 ) ) FWT_{or}(A)=(FWT_{or}(A0),FWT_{or}(A0+A1)) FWTor(A)=(FWTor(A0),FWTor(A0+A1))
简单地解释一下, F W T o r ( A 1 ) FWT_{or}(A1) FWTor(A1)无法对 F W T o r ( A ) FWT_{or}(A) FWTor(A)的前半部分造成影响,因为A1部分的下标肯定不是A0部分下标的子集,(*)式中j的最高位只能为0

而对于 F W T o r ( A ) FWT_{or}(A) FWTor(A)的后半部分,最高位为1,也就是说,(*)式中j的最高位可以取0或1,也就是后半部分要把 F W T o r ( A 1 ) FWT_{or}(A1) FWTor(A1) F W T o r ( A 0 ) FWT_{or}(A0) FWTor(A0)合并起来

(不知道有没有讲清楚,如果没有的话,建议多理解一下(*)式)

当然,逆变换也非常显然,就只用把高位加的 F W T o r ( A 0 ) FWT_{or}(A0) FWTor(A0)减掉就好了
U F W T o r ( B ) = ( U F W T o r ( B 0 ) , U F W T o r ( B 0 − B 1 ) ) UFWT_{or}(B)=(UFWT_{or}(B0),UFWT_{or}(B0-B1)) UFWTor(B)=(UFWTor(B0),UFWTor(B0B1))

与卷积

这里就只给三个公式,用或卷积里的替换一下就好了

(*)式:
F W T a n d ( A ) [ i ] = ∑ i & j = i a j    ( ∗ ) FWT_{and}(A)[i]=\sum_{i\&j=i}a_j\ \ (*) FWTand(A)[i]=i&j=iaj  ()
变换:
F W T a n d ( A ) = ( F W T a n d ( A 0 + A 1 ) , F W T a n d ( A 0 ) ) FWT_{and}(A)=(FWT_{and}(A0+A1),FWT_{and}(A0)) FWTand(A)=(FWTand(A0+A1),FWTand(A0))
逆变换:
U F W T a n d ( B ) = ( U F W T a n d ( B 0 − B 1 ) , U F W T a n d ( B 0 ) ) UFWT_{and}(B)=(UFWT_{and}(B0-B1),UFWT_{and}(B0)) UFWTand(B)=(UFWTand(B0B1),UFWTand(B0))

异或卷积

异或卷积的目标状态比较复杂
F W T x o r ( A ) [ i ] = ∑ c n t 1 ( i & j ) 为 偶 数 a j − ∑ c n t 1 ( i & j ) 为 奇 数 a j    ( ∗ ) FWT_{xor}(A)[i]=\sum_{cnt1(i\&j)为偶数}a_j-\sum_{cnt1(i\&j)为奇数}a_j\ \ (*) FWTxor(A)[i]=cnt1(i&j)ajcnt1(i&j)aj  ()

c n t 1 ( ) cnt1() cnt1()指二进制下1的个数

F W T x o r ( C ) [ i ] = F W T x o r ( A ) [ i ] ∗ F W T x o r ( B ) [ i ] FWT_{xor}(C)[i]=FWT_{xor}(A)[i]*FWT_{xor}(B)[i] FWTxor(C)[i]=FWTxor(A)[i]FWTxor(B)[i]

上式乘积的正确性证明就让大家自己证啦(太长了Latex写不动)

变换的公式:
F W T x o r ( A ) = ( F W T x o r ( A 0 + A 1 ) , F W T x o r ( A 0 − A 1 ) ) FWT_{xor}(A)=(FWT_{xor}(A0+A1),FWT_{xor}(A0-A1)) FWTxor(A)=(FWTxor(A0+A1),FWTxor(A0A1))
理解:

对于前半部分来说,最高位补0对于 F W T x o r ( A 0 ) , F W T x o r ( A 1 ) FWT_{xor}(A0),FWT_{xor}(A1) FWTxor(A0),FWTxor(A1)来说不会影响(*)式中 c n t 1 ( i & j ) cnt1(i\&j) cnt1(i&j)的奇偶性,所以可以直接相加作为前半部分的结果

对于后半部分来说 F W T x o r ( A 0 ) FWT_{xor}(A0) FWTxor(A0)最高位补1仍然不影响(*)式中 c n t 1 ( i & j ) cnt1(i\&j) cnt1(i&j)的奇偶性(1&0还是0嘛),而 F W T x o r ( A 1 ) FWT_{xor}(A1) FWTxor(A1)的最高位补1会引入一个新的1,这会导致奇偶性翻转,所以后半部分就成了 F W T x o r ( A 0 − A 1 ) FWT_{xor}(A0-A1) FWTxor(A0A1)

然后对于逆变换来说就是解个方程就得到了
U F W T x o r ( B ) = ( U F W T o r ( B 0 + B 1 ) / 2 , U F W T o r ( B 0 − B 1 ) / 2 ) UFWT_{xor}(B)=(UFWT_{or}(B0+B1)/2,UFWT_{or}(B0-B1)/2) UFWTxor(B)=(UFWTor(B0+B1)/2,UFWTor(B0B1)/2)

同或卷积

照着异或卷积魔改一下就好了(cnt1改成cnt0,&改成|之类的)

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值