快速沃尔什变换(FWT)

本文介绍了FWT(FastWalshTransform)在解决位运算卷积问题中的方法,通过分治策略将多项式分解并利用位运算特性快速计算,以O(n)的复杂度实现与、或、异或的卷积操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简介 \huge 简介 简介

F W T FWT FWT 是用于解决对下表进行位运算卷积问题的方法

更确切地说,给定两个多项式 A A A B B B ,求多项式 C C C

c i = ∑ i = j ⊕ k a j b k c_i = \sum _{i=j⊕k}a_jb_k ci=i=jkajbk

其中, ⊕表示任意位运算符号(与(&),或(|),异或(^)之一)

F F T FFT FFT 类似, F W T FWT FWT 先将 A , B A,B A,B 转换成 F W T FWT FWT 的形式,相乘后再用逆变换转换成多项式形式。

以下会对三种位运算符号分别推导。



或 \huge 或

要求

c i = ∑ i = j ∥ k a j b k c_i = \sum _{i=j\|k}a_jb_k ci=i=jkajbk

F W T [ a ] i FWT[a]_i FWT[a]i 表示为 a a a 转成 F W T FWT FWT 形势下的第 i i i

构造 F W T [ a ] _ i = ∑ j ∥ i = i a j FWT[a]\_i = \sum_{j\|i=i}a_j FWT[a]_i=ji=iaj

F W T [ a ] _ i × F W T [ b ] _ i = ( ∑ j ∥ i = i a j ) ( ∑ k ∥ i = i b k )                       FWT[a]\_i \times FWT[b]\_i = \left( \sum_{j\|i=i}a_j \right) \left( \sum_{k\|i=i}b_k\right)\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ FWT[a]_i×FWT[b]_i= ji=iaj ki=ibk                      

= ∑ j ∣ i = i ∑ k ∣ i = i a j b k =\sum_{j|i=i} \sum_{k|i=i}a_jb_k =ji=iki=iajbk

= ∑ ( j ∣ k ) ∣ i = i a j b k    =\sum_{(j|k)|i=i}a_jb_k\ \ =(jk)i=iajbk  

= F W T [ c ] i       =FWT[c]_i\ \ \ \ \ =FWT[c]i     

且就是说可以通过按位相乘的方式,以 O ( n ) O(n) O(n) 的复杂度解决两个 F W T FWT FWT 的卷积。

接下来要解决的是如何求一个多项式的 F W T FWT FWT

采用分治策略,每一次将多项式分为左半边 a 0 a_0 a0 和右半边 a 1 a_1 a1

其一定满足左半边下标最高位为 0 0 0 ,右半边下标最高位为 1 1 1

QQ截图20230504142542.png

如图所示,先分别计算两边的值,由于 0 ∣ 1 = 1 0|1=1 0∣1=1 ,所以最终合并的结果为

F W T [ a ] = m e r g e ( F W T [ a 0 ] , F W T [ a 0 ] + F W T [ a 1 ] ) FWT[a] = merge(FWT[a_0],FWT[a_0]+FWT[a_1]) FWT[a]=merge(FWT[a0],FWT[a0]+FWT[a1])

其中 + + + 表示按位相加。

易得反演递推式:

U F W T [ a ] = m e r g e ( U F W T [ a 0 ] , U F W T [ a 1 ] − U F W T [ a 0 ] ) UFWT[a] = merge(UFWT[a_0],UFWT[a_1] - UFWT[a_0]) UFWT[a]=merge(UFWT[a0],UFWT[a1]UFWT[a0])

实现 实现 实现

void OR(int *a, int x) {
	for (int o = 2, k = 1; o <= n; o <<= 1, k <<= 1)
		for (int i = 0; i < n; i += o)
			for (int j = 0; j < k; j ++ )
				a[i + j + k] = a[i + j + k] + a[i + j] * x;
}


与 \Huge 与

要求

c i = ∑ j & k = i a j b k c_i = \sum_{j\&k=i} a_jb_k ci=j&k=iajbk

构造 F W T [ a ] _ i = ∑ j & i = i a j FWT[a]\_i = \sum _{j\&i=i} a_j FWT[a]_i=j&i=iaj

F W T [ a ] _ i × F W T [ b ] _ i = ( ∑ j & i = i a j ) ( ∑ k & i = i b k )                         FWT[a]\_i \times FWT[b]\_i = \left( \sum_{j\&i=i}a_j \right) \left( \sum_{k\&i=i}b_k\right)\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ FWT[a]_i×FWT[b]_i= j&i=iaj (k&i=ibk)                       

= ∑ j & i = i ∑ k & i = i a j b k =\sum_{j\&i=i} \sum_{k\&i=i}a_jb_k =j&i=ik&i=iajbk

= ∑ ( j & k ) & i = i a j b k    =\sum_{(j\&k)\&i=i}a_jb_k\ \ =(j&k)&i=iajbk  

= F W T [ c ] i          =FWT[c]_i\ \ \ \ \ \ \ \ =FWT[c]i        

同上或的递推式,由于 0 & 1 = 0 0\&1=0 0&1=0 ,所以递推式为

F W T [ a ] = m e r g e ( F W T [ a 0 ] + F W T [ a 1 ] , F W T [ a 1 ] ) FWT[a] = merge(FWT[a_0]+FWT[a_1],FWT[a_1]) FWT[a]=merge(FWT[a0]+FWT[a1],FWT[a1])

U F W T [ a ] = m e r g e ( U F W T [ a 0 ] − U F W T [ a 1 ] , U F W T [ a 1 ] ) UFWT[a] = merge(UFWT[a_0]-UFWT[a_1],UFWT[a_1]) UFWT[a]=merge(UFWT[a0]UFWT[a1],UFWT[a1])

实现 实现 实现

void AND(int *a, int x) {
	for (int o = 2, k = 1; o <= n; o <<= 1, k <<= 1)
		for (int i = 0; i < n; i += o)
			for (int j = 0; j < k; j ++ )
				a[i + j] = a[i + j] + a[i + j + k] * x;
}


异或 \Huge 异或 异或

定义 x ⊗ y = p o p c o u n t ( x & y )   m o d   2 x⊗y=popcount(x\&y) \bmod 2 xy=popcount(x&y)mod2,其中 p o p c o u n t popcount popcount 表示二进制下 1 1 1 的个数

满足 ( i ⊗ j ) xor ( i ⊗ k ) = i ⊗ ( j   xor   k ) (i⊗j) \textsf{xor} (i⊗k) = i⊗(j \ \textsf{xor} \ k) (ij)xor(ik)=i(j xor k)

构造 f w t [ a ] _ i = ∑ i ⊗ j = 0 a j − ∑ i ⊗ j = 1 a j fwt[a]\_i=\sum_{i⊗j=0}a_j-\sum_{i⊗j=1}a_j fwt[a]_i=ij=0ajij=1aj

则有

f w t [ a ] _ i × f w t [ b ] _ i = ( ∑ i ⊗ j = 0 a j − ∑ i ⊗ j = 1 a j ) ( ∑ i ⊗ k = 0 b k − ∑ i ⊗ k = 1 b k )            fwt[a]\_i \times fwt[b]\_i = \left( \sum_{i⊗j=0}a_j-\sum_{i⊗j=1}a_j \right) \left( \sum_{i⊗k=0}b_k-\sum_{i⊗k=1}b_k \right)\ \ \ \ \ \ \ \ \ \ fwt[a]_i×fwt[b]_i=(ij=0ajij=1aj)(ik=0bkik=1bk)          

= ∑ i ⊗ ( j   xor   k ) = 0 a j b k − ∑ i ⊗ ( j   xor   k ) = 1 a j b k =\sum_{i⊗(j\ \textsf{xor}\ k)=0}a_jb_k - \sum_{i⊗(j\ \textsf{xor} \ k)=1}a_jb_k =i(j xor k)=0ajbki(j xor k)=1ajbk

= f w t [ c ] i                                            =fwt[c]_i\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =fwt[c]i                                          

根据定义得出

F W T [ a ] = m e r g e ( F W T [ a 0 ] + F W T [ a 1 ] , F W T [ a 0 ] − F W T [ a 1 ] ) FWT[a] = merge(FWT[a_0]+FWT[a_1],FWT[a_0]-FWT[a_1]) FWT[a]=merge(FWT[a0]+FWT[a1],FWT[a0]FWT[a1])

U F W T [ a ] = m e r g e ( U F W T [ a 0 ] + U F W T [ a 1 ] 2 , U F W T [ a 0 ] − U F W T [ a 1 ] 2 ) UFWT[a] = merge(\frac{UFWT[a_0]+UFWT[a_1]}{2},\frac{UFWT[a_0]-UFWT[a_1]}{2}) UFWT[a]=merge(2UFWT[a0]+UFWT[a1],2UFWT[a0]UFWT[a1])

实现 实现 实现

void XOR(int *a, int x) {
	for (int o = 2, k = 1; o <= n; o <<= 1, k <<= 1)
		for (int i = 0; i < n; i += o)
			for (int j = 0; j < k; j ++ ) {
				a[i + j] = a[i + j] + a[i + j + k];
				a[i + j + k] = a[i + j] - a[i + j + k] - a[i + j + k];
				a[i + j] = a[i + j] * x, a[i + j + k] = a[i + j + k] * x;
			}
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值