快速沃尔什变换:从入门到背板(含推导过程)
前(che)言(dan)
FWTFWTFWT是個神奇的東西。
然而網(wǎng)上多數(shù)講解多數(shù)直接給結(jié)論,頂多用歸納法證一證。
所以本文會講解FWTFWTFWT的推導(dǎo)過程。
雖然也用到了構(gòu)造,但是好背得多
參考博客:https://www.cnblogs.com/ACMSN/p/11031072.html
能干啥
眾所周知,FFTFFTFFT求的是
Ck=∑i+j=kAiBjC_k=\sum_{i+j=k}A_iB_jCk?=i+j=k∑?Ai?Bj?
而FWTFWTFWT求的是
Ck=∑i⊕j=kAiBjC_k=\sum_{i\oplus j=k}A_iB_jCk?=i⊕j=k∑?Ai?Bj?
其中⊕\oplus⊕為邏輯位運算符,即&,∣,^\&,|,\hat{}&,∣,^
兩者思想類似,但實際上是兩條不同的線。
約定
大寫字母A,B,CA,B,CA,B,C表示一個序列(多項式),下標從000開始,到n?1n-1n?1結(jié)束
小寫字母i,j,ki,j,ki,j,k表示循環(huán)變量
A+B,A?B,A?BA+B,A-B,A*BA+B,A?B,A?B表示對應(yīng)位直接相加,相減或相乘
A⊕BA \oplus BA⊕B表示對應(yīng)的卷積,⊕\oplus⊕為&,∣,^,×(乘法)\&,|,\hat{},\times(乘法)&,∣,^,×(乘法)
A[i]A[i]A[i]表示序列第iii位
A0,A1A_0,A_1A0?,A1?表示序列前半部分和后半部分
(A,B)(A,B)(A,B)表示將兩個序列拼接在一起
如果涉及了集合運算,表示這個數(shù)二進制111的位置構(gòu)成的集合
分析
回憶FFTFFTFFT的過程,它的思想是構(gòu)造一個FFTFFTFFT函數(shù)及其逆運算IFFTIFFTIFFT,使得
IFFT(FFT(A)?FFT(B))=A×BIFFT(FFT(A)*FFT(B))=A \times BIFFT(FFT(A)?FFT(B))=A×B
FWTFWTFWT則構(gòu)造
IFWT(FWT(A)?FWT(B))=A⊕BIFWT(FWT(A)*FWT(B))=A \oplus BIFWT(FWT(A)?FWT(B))=A⊕B
以下都假裝NNN是222的整數(shù)次冪
先說主要思想:構(gòu)造一個i,ji,ji,j的關(guān)系式g(i,j)g(i,j)g(i,j),使得
FWT(A)[i]=∑j=0n?1g(i,j)A[j]FWT(A)[i]=\sum_{j=0}^{n-1}g(i,j)A[j]FWT(A)[i]=j=0∑n?1?g(i,j)A[j]
我們想要
FWT(A⊕B)=FWT(A)?FWT(B)FWT(A\oplus B)=FWT(A)*FWT(B)FWT(A⊕B)=FWT(A)?FWT(B)
即對于任意的iii
FWT(A⊕B)[i]=FWT(A)[i]?FWT(B)[i]FWT(A\oplus B)[i]=FWT(A)[i]*FWT(B)[i]FWT(A⊕B)[i]=FWT(A)[i]?FWT(B)[i]
代入
∑j=0n?1g(i,j)((A⊕B)[j])=∑j=0n?1g(i,j)A[j]∑k=0n?1g(i,k)B[k]\sum_{j=0}^{n-1}g(i,j)((A \oplus B)[j])=\sum_{j=0}^{n-1}g(i,j)A[j]\sum_{k=0}^{n-1}g(i,k)B[k]j=0∑n?1?g(i,j)((A⊕B)[j])=j=0∑n?1?g(i,j)A[j]k=0∑n?1?g(i,k)B[k]
拆開
∑x=0n?1g(i,x)∑j⊕k=xA[j]?B[k]=∑j=0n?1g(i,j)A[j]∑k=0n?1g(i,k)B[k]\sum_{x=0}^{n-1}g(i,x)\sum_{j\oplus k=x}A[j]*B[k]=\sum_{j=0}^{n-1}g(i,j)A[j]\sum_{k=0}^{n-1}g(i,k)B[k]x=0∑n?1?g(i,x)j⊕k=x∑?A[j]?B[k]=j=0∑n?1?g(i,j)A[j]k=0∑n?1?g(i,k)B[k]
右邊可以乘法分配率合并(其實就是換個順序)
∑x=0n?1g(i,x)∑j⊕k=xA[j]?B[k]=∑j=0n?1∑k=0n?1g(i,j)g(i,k)A[j]B[k]\sum_{x=0}^{n-1}g(i,x)\sum_{j\oplus k=x}A[j]*B[k]=\sum_{j=0}^{n-1}\sum_{k=0}^{n-1}g(i,j)g(i,k)A[j]B[k]x=0∑n?1?g(i,x)j⊕k=x∑?A[j]?B[k]=j=0∑n?1?k=0∑n?1?g(i,j)g(i,k)A[j]B[k]
左邊更換枚舉項
∑j=0n?1∑k=0n?1g(i,j⊕k)A[j]B[k]=∑j=0n?1∑k=0n?1g(i,j)g(i,k)A[j]B[k]\sum_{j=0}^{n-1}\sum_{k=0}^{n-1}g(i,j\oplus k)A[j]B[k]=\sum_{j=0}^{n-1}\sum_{k=0}^{n-1}g(i,j)g(i,k)A[j]B[k]j=0∑n?1?k=0∑n?1?g(i,j⊕k)A[j]B[k]=j=0∑n?1?k=0∑n?1?g(i,j)g(i,k)A[j]B[k]
即:
g(i,j⊕k)=g(i,j)g(i,k)g(i,j\oplus k)=g(i,j)g(i,k)g(i,j⊕k)=g(i,j)g(i,k)
我們還需要證一個東西:
FWT(A+B)=FWT(A)+FWT(B)FWT(A+B)=FWT(A)+FWT(B)FWT(A+B)=FWT(A)+FWT(B)
對于每個iii
FWT(A+B)[i]=FWT(A)[i]+FWT(B)[i]FWT(A+B)[i]=FWT(A)[i]+FWT(B)[i]FWT(A+B)[i]=FWT(A)[i]+FWT(B)[i]
套定義
∑j=0n?1g(i,j)(A+B)[j]=∑j=0n?1g(i,j)A[j]+∑j=0n?1g(i,j)B[j]\sum_{j=0}^{n-1}g(i,j)(A+B)[j]=\sum_{j=0}^{n-1}g(i,j)A[j]+\sum_{j=0}^{n-1}g(i,j)B[j]j=0∑n?1?g(i,j)(A+B)[j]=j=0∑n?1?g(i,j)A[j]+j=0∑n?1?g(i,j)B[j]
然后很顯然 證畢
完結(jié)撒花
或
構(gòu)造
g(i,j∣k)=g(i,j)g(i,k)g(i,j | k)=g(i,j)g(i,k)g(i,j∣k)=g(i,j)g(i,k)
寫成集合形式
g(i,j∪k)=g(i,j)g(i,k)g(i,j \cup k)=g(i,j)g(i,k)g(i,j∪k)=g(i,j)g(i,k)
構(gòu)造g(i,j)=[j?i]g(i,j)=[j \subset i]g(i,j)=[j?i]即可
實現(xiàn)
FWT(A)[i]=∑j?iA[j]FWT(A)[i]=\sum_{j\subset i}A[j]FWT(A)[i]=j?i∑?A[j]
考慮分治
將一個序列分成左右兩部分,左邊最高位為000 右邊最高位為111
對于左邊,其子集就是上一個的子集
右邊再加上左邊,因為可以不選最高位
即
FWT(A)=(FWT(A0),FWT(A0)+FWT(A1))FWT(A)=(FWT(A_0),FWT(A_0)+FWT(A_1))FWT(A)=(FWT(A0?),FWT(A0?)+FWT(A1?))
只有一項直接返回
逆運算解個方程就行了
{FWT(A)0=FWT(A0)FWT(A)1=FWT(A0)+FWT(A1)\left\{ \begin{aligned} FWT(A)_0 & = FWT(A_0) \\ FWT(A)_1 & = FWT(A_0)+FWT(A_1) \end{aligned} \right. {FWT(A)0?FWT(A)1??=FWT(A0?)=FWT(A0?)+FWT(A1?)?
{FWT(A0)=FWT(A)0FWT(A1)=FWT(A)1?FWT(A)0\left\{ \begin{aligned} FWT(A_0) & = FWT(A)_0 \\ FWT(A_1) & = FWT(A)_1-FWT(A)_0 \end{aligned} \right. {FWT(A0?)FWT(A1?)?=FWT(A)0?=FWT(A)1??FWT(A)0??
即
IFWT(A)=(IFWT(A0),IFWT(A1)?IFWT(A0))IFWT(A)=(IFWT(A_0),IFWT(A_1)-IFWT(A_0))IFWT(A)=(IFWT(A0?),IFWT(A1?)?IFWT(A0?))
與
同理,略
FWT(A)=(FWT(A0)+FWT(A1),FWT(A1))FWT(A)=(FWT(A_0)+FWT(A_1),FWT(A_1))FWT(A)=(FWT(A0?)+FWT(A1?),FWT(A1?))
IFWT(A)=(IFWT(A0)?IFWT(A1),IFWT(A1))IFWT(A)=(IFWT(A_0)-IFWT(A_1),IFWT(A_1))IFWT(A)=(IFWT(A0?)?IFWT(A1?),IFWT(A1?))
異或
構(gòu)造
g(i,j^k)=g(i,j)g(i,k)g(i,j \hat{\quad} k)=g(i,j)g(i,k)g(i,j^k)=g(i,j)g(i,k)
我也不知道怎么想到的構(gòu)造
g(i,j)=(?1)∣i∩j∣g(i,j)=(-1)^{|i\cap j|}g(i,j)=(?1)∣i∩j∣
用到了異或不會改變111的總數(shù)的奇偶性 意識流得證
實現(xiàn)
FWT(A)[i]=∑j=0n?1(?1)∣i∩j∣A[j]FWT(A)[i]=\sum_{j=0}^{n-1}(-1)^{|i\cap j|}A[j]FWT(A)[i]=j=0∑n?1?(?1)∣i∩j∣A[j]
仍然分成左右兩部分,右邊表示選擇最高位
發(fā)現(xiàn)只有兩側(cè)都填111的時候會改變∣i∩j∣|i\cap j|∣i∩j∣的奇偶性,相當于產(chǎn)生負的貢獻。其余都產(chǎn)生正貢獻。
即
FWT(A)=(FWT(A0)+FWT(A1),FWT(A0)?FWT(A1))FWT(A)=(FWT(A_0)+FWT(A_1),FWT(A_0)-FWT(A_1))FWT(A)=(FWT(A0?)+FWT(A1?),FWT(A0?)?FWT(A1?))
IFWT(A)=(IFWT(A0)+IFWT(A1)2,IFWT(A0)?IFWT(A1)2)IFWT(A)=(\frac{IFWT(A_0)+IFWT(A_1)}{2},\frac{IFWT(A_0)-IFWT(A_1)}{2})IFWT(A)=(2IFWT(A0?)+IFWT(A1?)?,2IFWT(A0?)?IFWT(A1?)?)
代碼
void ForT(int* a,int n,int type) {for (int len=2;len<=(1<<n);len<<=1){int mid=len>>1;for (int s=0;s<(1<<n);s+=len)for (int k=0;k<mid;k++){a[s+mid+k]=(a[s+mid+k]+type*a[s+k])%MOD;if (a[s+mid+k]<0) a[s+mid+k]+=MOD;}} } void FandT(int* a,int n,int type) {for (int len=2;len<=(1<<n);len<<=1){int mid=len>>1;for (int s=0;s<(1<<n);s+=len)for (int k=0;k<mid;k++){a[s+k]=(a[s+k]+type*a[s+mid+k])%MOD;if (a[s+k]<0) a[s+k]+=MOD;}} } void FxorT(int* a,int n,int type) {for (int len=2;len<=(1<<n);len<<=1){int mid=len>>1;for (int s=0;s<(1<<n);s+=len)for (int k=0;k<mid;k++){a[s+k]=(a[s+k]+a[s+mid+k])%MOD;a[s+mid+k]=(a[s+k]-2*a[s+mid+k])%MOD;if (a[s+mid+k]<0) a[s+mid+k]+=MOD;if (type==-1) a[s+k]=(ll)a[s+k]*INV%MOD,a[s+mid+k]=(ll)a[s+mid+k]*INV%MOD;}} } 創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的快速沃尔什变换:从入门到背板(含推导过程)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 换电信路由器怎么设置电信更换宽带路由器怎
- 下一篇: 能产生可移动的纸质照片能产生可移动的纸质