快速沃尔什变换学习小记

定义

AAABBB均是长度为n=2kn=2^kn=2k的数组。定义A0A_0A0为这个数组的前2n−12^{n-1}2n1项,A1A_1A1为这个数组的后2n−12^{n-1}2n1项,那么有A=(A0,A1)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=0A[i]∗B[j],∑i@j=1A[i]∗B[j],...,∑i@j=n−1A[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,BA,BA,B,求C=A@BC=A@BC=A@B

快速沃尔什变换

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

XOR

根据异或运算的性质,不难得到A@B=(A0⊕B0+A1⊕B1,A0⊕B1+A1⊕B0)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运算满足交换律,分配律和结合律。
定义运算Fwt(A)Fwt(A)Fwt(A)
Fwt(A)={(Fwt(A0+A1),Fwt(A0−A1))n>1An=1Fwt(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

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

性质2

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

=Fwt(A0⊕B0+A1⊕B1,A0⊕B1+A1⊕B0)=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(A0⊕B0+A1⊕B1+A0⊕B1+A1⊕B0),Fwt(A0⊕B0+A1⊕B1−A0⊕B1−A1⊕B0))=(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))

=(Fwt((A0+A1)⊕(B0+B1)),Fwt((A0−A1)⊕(B0−B1)))=(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)))

=(Fwt(A0+A1)∗Fwt(B0+B1),Fwt(A0−A1)∗Fwt(B0−B1))=(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))

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

=Fwt(A)∗Fwt(B)=Fwt(A)*Fwt(B)=Fwt(A)Fwt(B)
证毕。

逆变换

Dwt(Fwt(A))Dwt(Fwt(A))Dwt(Fwt(A))

=Dwt(Fwt(A0+A1),Fwt(A0−A1))=Dwt(Fwt(A_0+A_1),Fwt(A_0-A_1))=Dwt(Fwt(A0+A1),Fwt(A0A1))

=Dwt(Fwt(A0)+Fwt(A1),Fwt(A0)−Fwt(A1))=Dwt(Fwt(A_0)+Fwt(A_1),Fwt(A_0)-Fwt(A_1))=Dwt(Fwt(A0)+Fwt(A1),Fwt(A0)Fwt(A1))

Dwt(A)=(Dwt(A0+A12),Dwt(A0−A12))Dwt(A)=(Dwt(\frac{A_0+A_1}{2}),Dwt(\frac{A_0-A_1}{2}))Dwt(A)=(Dwt(2A0+A1),Dwt(2A0A1))

那么有Dwt(Fwt(A))Dwt(Fwt(A))Dwt(Fwt(A))

=(Dwt(Fwt(A0)),Dwt(Fwt(A1)))=(Dwt(Fwt(A_0)),Dwt(Fwt(A_1)))=(Dwt(Fwt(A0)),Dwt(Fwt(A1)))

=(A0,A1)=(A_0,A_1)=(A0,A1)

求解

在求解C=A⊕BC=A\oplus BC=AB的时候,可以先对AAABBB分别做FwtFwtFwt,得到A′A'AB′B'B
C′=A′∗B′C'=A'*B'C=AB,那么C=Dwt(C′)C=Dwt(C')C=Dwt(C)
时间复杂度O(nlogn)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

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

OR

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

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值