快速沃尔什变换学习小记

定义

A A A B B B均是长度为 n = 2 k n=2^k n=2k的数组。定义 A 0 A_0 A0为这个数组的前 2 n − 1 2^{n-1} 2n1项, A 1 A_1 A1为这个数组的后 2 n − 1 2^{n-1} 2n1项,那么有 A = ( A 0 , A 1 ) A=(A_0,A_1) A=(A0,A1)
A + B = ( A [ 0 ] + B [ 0 ] , A [ 1 ] + B [ 1 ] , . . . , A [ n − 1 ] + B [ n − 1 ] ) A+B=(A[0]+B[0],A[1]+B[1],...,A[n-1]+B[n-1]) A+B=(A[0]+B[0],A[1]+B[1],...,A[n1]+B[n1])
A ∗ B = ( A [ 0 ] ∗ B [ 0 ] , A [ 1 ] ∗ B [ 1 ] , . . . , A [ n − 1 ] ∗ B [ n − 1 ] ) A*B=(A[0]*B[0],A[1]*B[1],...,A[n-1]*B[n-1]) AB=(A[0]B[0],A[1]B[1],...,A[n1]B[n1])
A @ B = ( ∑ i @ j = 0 A [ i ] ∗ B [ j ] , ∑ i @ j = 1 A [ i ] ∗ B [ j ] , . . . , ∑ i @ j = n − 1 A [ i ] ∗ B [ j ] ) A@B=(\sum_{i@j=0}A[i]*B[j],\sum_{i@j=1}A[i]*B[j],...,\sum_{i@j=n-1}A[i]*B[j]) A@B=(i@j=0A[i]B[j],i@j=1A[i]B[j],...,i@j=n1A[i]B[j])

目标

给出 A , B A,B A,B,求 C = A @ B C=A@B C=A@B

快速沃尔什变换

快速沃尔什变换(简称FWT),就是用来解决这样一类问题的算法。其中 @ @ @运算可以是异或,与,或之类的位运算。
这里主要介绍异或运算。

XOR

根据异或运算的性质,不难得到 A @ B = ( A 0 ⊕ B 0 + A 1 ⊕ B 1 , A 0 ⊕ B 1 + A 1 ⊕ B 0 ) A@B=(A_0\oplus B_0+A_1\oplus B_1,A_0\oplus B_1+A_1\oplus B_0) A@B=(A0B0+A1B1,A0B1+A1B0)
且不难验证 ⊕ \oplus 运算满足交换律,分配律和结合律。
定义运算 F w t ( A ) Fwt(A) Fwt(A)
F w t ( A ) = { ( F w t ( A 0 + A 1 ) , F w t ( A 0 − A 1 ) ) n > 1 A n = 1 Fwt(A) = \begin{cases} (Fwt(A_0+A_1),Fwt(A_0-A_1)) & n>1 \\ A & n=1 \end{cases} Fwt(A)={(Fwt(A0+A1),Fwt(A0A1))An>1n=1

性质1

F w t ( A + B ) = F w t ( A ) + F w t ( B ) Fwt(A+B)=Fwt(A)+Fwt(B) Fwt(A+B)=Fwt(A)+Fwt(B)
证明:不难发现 F w t ( A ) Fwt(A) Fwt(A)的每一项都是 A A A的一个线性组合,故满足加法分配律。

性质2

F w t ( A ⊕ B ) = F w t ( A ) ∗ F w t ( B ) Fwt(A\oplus B)=Fwt(A)*Fwt(B) Fwt(AB)=Fwt(A)Fwt(B)
证明:用数学归纳法来证。
n = 1 n=1 n=1时显然成立。
n > 1 n>1 n>1时有
F w t ( A ⊕ B ) Fwt(A\oplus B) Fwt(AB)

= F w t ( A 0 ⊕ B 0 + A 1 ⊕ B 1 , A 0 ⊕ B 1 + A 1 ⊕ B 0 ) =Fwt(A_0\oplus B_0+A_1\oplus B_1,A_0\oplus B_1+A_1\oplus B_0) =Fwt(A0B0+A1B1,A0B1+A1B0)

= ( F w t ( A 0 ⊕ B 0 + A 1 ⊕ B 1 + A 0 ⊕ B 1 + A 1 ⊕ B 0 ) , F w t ( A 0 ⊕ B 0 + A 1 ⊕ B 1 − A 0 ⊕ B 1 − A 1 ⊕ B 0 ) ) =(Fwt(A_0\oplus B_0+A_1\oplus B_1+A_0\oplus B_1+A_1\oplus B_0),Fwt(A_0\oplus B_0+A_1\oplus B_1-A_0\oplus B_1-A_1\oplus B_0)) =(Fwt(A0B0+A1B1+A0B1+A1B0),Fwt(A0B0+A1B1A0B1A1B0))

= ( F w t ( ( A 0 + A 1 ) ⊕ ( B 0 + B 1 ) ) , F w t ( ( A 0 − A 1 ) ⊕ ( B 0 − B 1 ) ) ) =(Fwt((A_0+A_1)\oplus (B_0+B_1)),Fwt((A_0-A_1)\oplus (B_0-B_1))) =(Fwt((A0+A1)(B0+B1)),Fwt((A0A1)(B0B1)))

= ( F w t ( A 0 + A 1 ) ∗ F w t ( B 0 + B 1 ) , F w t ( A 0 − A 1 ) ∗ F w t ( B 0 − B 1 ) ) =(Fwt(A_0+A_1)*Fwt(B_0+B_1),Fwt(A_0-A_1)*Fwt(B_0-B_1)) =(Fwt(A0+A1)Fwt(B0+B1),Fwt(A0A1)Fwt(B0B1))

= ( F w t ( A ) 0 ∗ F w t ( B ) 0 , F w t ( A ) 1 ∗ F w t ( B ) 1 ) =(Fwt(A)_0*Fwt(B)_0,Fwt(A)_1*Fwt(B)_1) =(Fwt(A)0Fwt(B)0,Fwt(A)1Fwt(B)1)

= F w t ( A ) ∗ F w t ( B ) =Fwt(A)*Fwt(B) =Fwt(A)Fwt(B)
证毕。

逆变换

D w t ( F w t ( A ) ) Dwt(Fwt(A)) Dwt(Fwt(A))

= D w t ( F w t ( A 0 + A 1 ) , F w t ( A 0 − A 1 ) ) =Dwt(Fwt(A_0+A_1),Fwt(A_0-A_1)) =Dwt(Fwt(A0+A1),Fwt(A0A1))

= D w t ( F w t ( A 0 ) + F w t ( A 1 ) , F w t ( A 0 ) − F w t ( A 1 ) ) =Dwt(Fwt(A_0)+Fwt(A_1),Fwt(A_0)-Fwt(A_1)) =Dwt(Fwt(A0)+Fwt(A1),Fwt(A0)Fwt(A1))

D w t ( A ) = ( D w t ( A 0 + A 1 2 ) , D w t ( A 0 − A 1 2 ) ) Dwt(A)=(Dwt(\frac{A_0+A_1}{2}),Dwt(\frac{A_0-A_1}{2})) Dwt(A)=(Dwt(2A0+A1),Dwt(2A0A1))

那么有 D w t ( F w t ( A ) ) Dwt(Fwt(A)) Dwt(Fwt(A))

= ( D w t ( F w t ( A 0 ) ) , D w t ( F w t ( A 1 ) ) ) =(Dwt(Fwt(A_0)),Dwt(Fwt(A_1))) =(Dwt(Fwt(A0)),Dwt(Fwt(A1)))

= ( A 0 , A 1 ) =(A_0,A_1) =(A0,A1)

求解

在求解 C = A ⊕ B C=A\oplus B C=AB的时候,可以先对 A A A B B B分别做 F w t Fwt Fwt,得到 A ′ A' A B ′ B' B
C ′ = A ′ ∗ B ′ C'=A'*B' C=AB,那么 C = D w t ( C ′ ) C=Dwt(C') C=Dwt(C)
时间复杂度 O ( n l o g n ) O(nlogn) O(nlogn)

代码

void fwt(int *a,int l,int r)
{
	if (l==r) return;
	int n=(r-l+1)/2,mid=l+n-1;
	fwt(a,l,mid);fwt(a,mid+1,r);
	for (int i=l;i<=mid;i++)
	{
		int x=a[i],y=a[i+n];
		a[i]=x+y;a[i+n]=x-y;
	}
}

void dwt(int *a,int l,int r)
{
	if (l==r) return;
	int n=(r-l+1)/2,mid=l+n-1;
	dwt(a,l,mid);dwt(a,mid+1,r);
	for (int i=l;i<=mid;i++)
	{
		int x=a[i],y=a[i+n];
		a[i]=(x+y)/2;a[i+n]=(x-y)/2;
	}
}

AND

@ @ @为与运算的时候,通过上述方法不难验证
F w t ( A ) = ( F w t ( A 0 + A 1 ) , F w t ( A 1 ) ) Fwt(A)=(Fwt(A_0+A_1),Fwt(A_1)) Fwt(A)=(Fwt(A0+A1),Fwt(A1))
D w t ( A ) = ( D w t ( A 0 − A 1 ) , F w t ( A 1 ) ) Dwt(A)=(Dwt(A_0-A_1),Fwt(A_1)) Dwt(A)=(Dwt(A0A1),Fwt(A1))

OR

@ @ @为或运算的时候,通过类比与运算不难验证
F w t ( A ) = ( F w t ( A 0 ) , F w t ( A 0 + A 1 ) ) Fwt(A)=(Fwt(A_0),Fwt(A_0+A_1)) Fwt(A)=(Fwt(A0),Fwt(A0+A1))
D w t ( A ) = ( D w t ( A 0 ) , D w t ( A 1 − A 0 ) ) Dwt(A)=(Dwt(A_0),Dwt(A_1-A_0)) Dwt(A)=(Dwt(A0),Dwt(A1A0))

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值