日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【learning】快速沃尔什变换FWT

發(fā)布時間:2024/1/17 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【learning】快速沃尔什变换FWT 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

問題描述

  已知\(A(x)\)\(B(x)\)\(C[i]=\sum\limits_{j\otimes k=i}A[j]*B[k]\),求\(C\)

  其中\(\otimes\)是三種位運(yùn)算的其中一種

具體求解

  說在前面:接下來的一些符號的話我們統(tǒng)一用\(\otimes\)代表某種位運(yùn)算(選定的),如果這個符號出現(xiàn)在兩個多項式之間(如:\(A\otimes B\)),那么是表示按照最上面那條式子卷積,如果出現(xiàn)在兩個數(shù)之間(如\(j\otimes k\)),那么是表示這兩個數(shù)進(jìn)行這種位運(yùn)算;然后我們用$?\cdot$這個符號表示點積(也就是對應(yīng)數(shù)位相乘)

?  這里我們用與運(yùn)算(\(\otimes=\&\))舉例說明好了,另外兩個差不多的

  首先來個不太靠譜的聯(lián)想,這個東西的名字長得跟FFT那么像那是不是可以借用FFT的形式啊(Portal -->FFT)

  然后我們考慮構(gòu)造一種變換\(F(A)\)(額其實就是FWT),其中\(A\)是一個多項式,這個變換滿足:
\[ \begin{aligned} &F(A)\cdot F(B)=F(A\otimes B)\\ &F(k* A)=k*F(A)\\ &F(A+B)=F(A)+F(B)\\ \end{aligned} \]
  這樣我們就可以像FFT一樣,先用某種方法求出\(F(A)\)\(F(B)\)然后對應(yīng)位相乘,再把得到的結(jié)果逆變換一下就可以得到\(C(x)\)

?  

  那么現(xiàn)在的問題是我們怎么構(gòu)造\(F\)

  參考FFT的求解我們還是嘗試用分治的思想來解決這個問題

?  與FFT按照下標(biāo)的奇偶性分類不同,因為位運(yùn)算是跟二進(jìn)制有關(guān)的,所以我們可以考慮按照下標(biāo)的二進(jìn)制最高位為\(0\)還是為\(1\)分成兩類(因為算的時候長度是補(bǔ)成\(2^k\)這樣的,所以其實也就是嚴(yán)格的前半部分和后半部分)

?  對于一個多項式\(A\),下標(biāo)二進(jìn)制最高位為\(0\)的那部分記為\(A_0\),為\(1\)的那部分記為\(A_1\)\(A=(A_0,A_1)\)

?  

?  我們可以猜測一下這個\(F(A)=(k_1A_0+k_2A_1,k_3A_0+k_4A_1)\)

  其中\(k_1,k_2,k_3,k_4\)都是常數(shù)

  然后現(xiàn)在我們要做的就是求出這四個常數(shù)

  

?  我們將\(A\otimes B\)寫成\((A_0,A_1)\otimes (B_0,B_1)\),然后看一下這個式子等于什么:

?  同樣的我們還是將結(jié)果寫成\((C_0,C_1)\)的形式,那么根據(jù)與運(yùn)算的特點我們可以的到:
\[ \begin{aligned} (A_0,A_1)\otimes (B_0,B_1)=(A_0\otimes B_0+A_0\otimes B_1+A_1\otimes B_0,A_1\otimes B_1)\\ \end{aligned} \]
?  (具體一點的話就是\(0\&0=0,0\&1=0,1\&0=0\)所以都是\(C_0\)的組成部分,只有\(1\&1=1\)\(C_1\)的組成部分)

  

  然后我們根據(jù)最上面的\(F\)這個變換滿足的性質(zhì)和我們猜測的\(F(A)=(k_1A_0+k_2A_1,k_3A_0+k_4A_1)\)來處理一下這個式子

?  (因為\(k_1,k_2\)\(k_3,k_4\)滿足的條件其實是一樣的所以在下面化的時候我們可以只考慮前半部分的求解(也就是就解\(k_1,k_2\),所有的變換什么的只寫前半部分),然后求得多組解最后取其中兩個可行解分別作為\(k_1,k_2,k_3,k_4\)即可)

?  (因為太長了。。所以一個等式我就換行來寫了qwq)
\[ \begin{aligned} &(k_1A_0+k_2A_1)\cdot (k_1B_0+k_2B_1)\\ =&k_1(A_0\otimes B_0+A_0\otimes B_1+A_1\otimes B_0)+ k_2(A_1\otimes B_1)\\ \\ &\Updownarrow\\ \\ &k_1^2(A_0\otimes B_0)+k_1k_2(A_0\otimes B_1)+k_1k_2(A_1\otimes B_0)+k_2^2(A_1\otimes B_1)\\ =&k_1(A_0\otimes B_0)+k_1(A_0\otimes B_1)+k_1(A_1\otimes B_0)+k_2(A_1\otimes B_1) \end{aligned} \]
  然后我們就可以直接得到一個比較好看的方程組了:
\[ \begin{cases} k_1^2=k_1\\ k_1k_2=k_1\\ k_2^2=k_2\\ \end{cases} \]
  然后我們解出來有三組解:\((0,0),(1,1),(0,1)\)

  接下來要做的就是從這三組解里面挑兩組出來作為\((k_1,k_2)\)\((k_3,k_4)\)

  但這個并不是隨便挑的,考慮到我們的這個變換必須要有一個逆變換,所以我們挑出來的兩組不能是有一組是\((0,0)\)或者有兩組相等(不然就不可逆了嘛),實際上,我們可以將這四個系數(shù)寫成一個矩陣,然后逆變換的系數(shù)的話就是對這個矩陣求個逆就好了

  所以,這里我們只能選\((1,1)\)\((0,1)\),我們令\((k_1,k_2)=(1,1)\)\((k_3,k_4)=(0,1)\)
\[ \begin{bmatrix} k_1&k_2\\ k_3&k_4\\ \end{bmatrix}= \begin{bmatrix} 1&1\\ 0&1\\ \end{bmatrix} \]
?  然后我們把這個東西求一下逆,得到逆矩陣:
\[ \begin{bmatrix} 1&-1\\ 0&1\\ \end{bmatrix} \]
?  (具體求解的話。。當(dāng)然可以直接用線代的那套但是qwq這里那么小那直接設(shè)數(shù)代一下就好了,設(shè)四個數(shù)然后矩乘一下等于單位矩陣)

?  然后我們按照這個系數(shù)去算FWT(也就是變換\(F\))和逆FWT就好啦

  然后如果是求異或或者是或運(yùn)算的話,那直接改一下
\[ (A_0,A_1)\otimes (B_0,B_1)=(A_0\otimes B_0+A_0\otimes B_1+A_1\otimes B_0,A_1\otimes B_1) \]
?  這個式子的左邊然后再用同樣的方法算一下就好了

  xor的話就是:\((A_0\otimes B_0+A_1\otimes B_1,A_0\otimes B_1+A_1\otimes B_0)\)

  or的話就是:\((A_0\otimes B_0,A_0\otimes B_1+A_1\otimes B_0+A_1\otimes B_1)\)

?  

  代碼什么的長得跟FFT其實差不多。。。哦不對。。會短很多ovo

?  大概是長這個樣子:

#define OR 0 #define AND 1 #define XOR 2void fwt(int *a,int op,int type,int len){//op=1為FWT,否則為逆FWTint v,u;for (int step=2;step<=len;step<<=1)for (int st=0;st<len;st+=step)for (int i=0;i<step>>1;++i){u=a[st+i]; v=a[st+i+(step>>1)];//u=A0,v=A1if (op==1){if (type==XOR)a[st+i]=(u+v)%MOD,a[st+i+(step>>1)]=(u+MOD-v)%MOD;else if (type==AND)a[st+i]=(u+v)%MOD;elsea[st+i+(step>>1)]=(u+v)%MOD;}else{if (type==XOR)a[st+i]=1LL*(u+v)*inv2%MOD,a[st+i+(step>>1)]=1LL*(1LL*u+MOD-v)*inv2%MOD;else if (type==AND)a[st+i]=(1LL*u-v+MOD)%MOD;elsea[st+i+(step>>1)]=(1LL*v-u+MOD)%MOD;//v-u!!}} }

轉(zhuǎn)載于:https://www.cnblogs.com/yoyoball/p/9260176.html

總結(jié)

以上是生活随笔為你收集整理的【learning】快速沃尔什变换FWT的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。