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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

模板:快速莫比乌斯变换(FMT)+快速沃尔什变换(FWT)(多项式)

發布時間:2023/12/3 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 模板:快速莫比乌斯变换(FMT)+快速沃尔什变换(FWT)(多项式) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 前言
  • 解析
    • OR
      • 定義
      • 變換:
      • 逆變換
      • 代碼
    • AND
      • 代碼
    • XOR
      • 定義
      • 變換
      • 逆變換
      • 代碼

所謂快速沃爾什變換,就是快速的沃爾瑪什錦專柜變換

(逃)

前言

正常卷積的定義:ck=∑i+j=kaibjc_k=\sum_{i+j=k}a_ib_jck?=i+j=k?ai?bj?
可以用FFT或者NTT在 O(nlog?n)O(n\log n)O(nlogn) 的復雜度內解決。
然而,有些時候,我們計算卷積的時候下標關系并不是喜聞樂見的加法,而是形如 ck=∑i⊕j=kaibjc_k=\sum_{i\oplus j=k}a_ib_jck?=ij=k?ai?bj?,其中的 ⊕\oplus 是 and or xor 中的一種位運算。
這個時候就需要快速莫比烏斯變換(and or)和快速沃爾什變換(xor),同樣可以把復雜度降到 O(nlog?n)O(n\log n)O(nlogn) 級別。

解析

由于三個運算思想比較類似,因此不對兩個算法進行特別的區分,統稱為FWT。
采用類比的思想,FFT先把多項式轉化為點值表示,乘到一起,最后再反演回去。
類似的,FWT也是先把多項式 A,BA,BA,B 轉化為某種變換 FWT?(A),FWT?(B)\operatorname{FWT}(A),\operatorname{FWT}(B)FWT(A),FWT(B),然后乘起來得到 FWT?(C)\operatorname{FWT}(C)FWT(C),最后再反演回去得到 CCC。
根據不同位運算的性質,對應的變換有所不同。

OR

定義

求:ck=∑i∣?j=kaibjc_k=\sum_{i\operatorname{|}j=k}a_ib_jck?=ij=k?ai?bj?
考慮或運算有如下性質:若 i∣k=k,j∣k=ki|k=k,j|k=kik=k,jk=k,那么 (i∣j)∣k=k(i|j)|k=k(ij)k=k,反之亦然。
那么我們就按照這個充要條件設計變換:FWT?or(A)k=∑i∣k=kAi\operatorname{FWT}_{or}(A)_k=\sum_{i|k=k}A_iFWTor?(A)k?=ik=k?Ai?
自然語言:iii 必須是 kkk子集才能轉移。
考慮兩個變換后的多項式逐項系數相乘
FWT?or(A)?FWT?or(B)=∑k(∑i∣k=kai)×(∑j∣k=kbj)\operatorname{FWT}_{or}(A)*\operatorname{FWT}_{or}(B)=\sum_{k}(\sum_{i|k=k}a_i)\times (\sum_{j|k=k}b_j)FWTor?(A)?FWTor?(B)=k?(ik=k?ai?)×(jk=k?bj?)
=∑k∑i∣k=k∑j∣k=kaibj=∑k∑(i∣j)∣k=kaibj=FWT?or(C)=\sum_{k}\sum_{i|k=k}\sum_{j|k=k}a_ib_j=\sum_{k}\sum_{(i|j)|k=k}a_ib_j=\operatorname{FWT}_{or}(C)=k?ik=k?jk=k?ai?bj?=k?(ij)k=k?ai?bj?=FWTor?(C)
所以我們就證出了系數直接相乘是對的,現在只需要一種快速的變換得到 FWT?or\operatorname{FWT}_{or}FWTor? 以及將其反演的方法。

變換:

還是和FFT類似的,考慮分治,假設我們要合并兩個長度為 2n2^n2n 的序列,設它們不同的最高位為1的序列為 A1A_1A1?,為0的為 A0A_0A0?
考慮 or的性質,A0A_0A0? 可以轉移到 A1A_1A1?,而 A1A_1A1? 無法轉移到 A0A_0A0?,因此有:
FWT?or(A)=(FWT?or(A0),FWT?or(A0)+FWT?or(A1))\operatorname{FWT}_{or}(A)=(\operatorname{FWT}_{or}(A_0),\operatorname{FWT}_{or}(A_0)+\operatorname{FWT}_{or}(A_1))FWTor?(A)=(FWTor?(A0?),FWTor?(A0?)+FWTor?(A1?))
其中 +++ 表示系數逐項相加(f(x),g(x))(f(x),g(x))(f(x),g(x)) 表示把 f(x)f(x)f(x)g(x)g(x)g(x) 順次寫出。

逆變換

那么對應的,還原成原序列只需要逆向操作即可:
UFWT?or(A)=(UFWT?or(A0),UFWT?or(A0)?UFWT?or(A1))\operatorname{UFWT}_{or}(A)=(\operatorname{UFWT}_{or}(A_0),\operatorname{UFWT}_{or}(A_0)-\operatorname{UFWT}_{or}(A_1))UFWTor?(A)=(UFWTor?(A0?),UFWTor?(A0?)?UFWTor?(A1?))

代碼

寫起來非常簡潔:

void Or(ll *x,int n,int op){for(int l=1;l<n;l<<=1){for(int st=0;st<n;st+=l*2){for(int i=0;i<l;i++){ll u=x[st+i],v=x[st+l+i];if(op==1) x[st+i]=u,x[st+l+i]=(v+u)%mod;else x[st+i]=u,x[st+l+i]=(v+mod-u)%mod;}}} }

AND

和 or 的整個定義、證明幾乎都是一樣的。
求:ck=∑i&?j=kaibjc_k=\sum_{i\operatorname{\&}j=k}a_ib_jck?=i&j=k?ai?bj?
與運算有如下性質:若 i&k=k,j&k=ki\&k=k,j\&k=ki&k=k,j&k=k,那么 (i&j)&k=k(i\&j)\&k=k(i&j)&k=k,反之亦然。
按照這個充要條件設計變換:FWT?or(A)k=∑i∣k=kAi\operatorname{FWT}_{or}(A)_k=\sum_{i|k=k}A_iFWTor?(A)k?=ik=k?Ai?
自然語言:iii 必須是 kkk超集才能轉移。
后面的證明一模一樣,變換也可以同理的得到:
FWT?and(A)=(FWT?and(A0)+FWT?and(A1),FWT?and(A1))\operatorname{FWT}_{and}(A)=(\operatorname{FWT}_{and}(A_0)+\operatorname{FWT}_{and}(A_1),\operatorname{FWT}_{and}(A_1))FWTand?(A)=(FWTand?(A0?)+FWTand?(A1?),FWTand?(A1?))
UFWT?and(A)=(UFWT?and(A0)?UFWT?and(A1),UFWT?and(A1))\operatorname{UFWT}_{and}(A)=(\operatorname{UFWT}_{and}(A_0)-\operatorname{UFWT}_{and}(A_1),\operatorname{UFWT}_{and}(A_1))UFWTand?(A)=(UFWTand?(A0?)?UFWTand?(A1?),UFWTand?(A1?))

代碼

void And(ll *x,int n,int op){for(int l=1;l<n;l<<=1){for(int st=0;st<n;st+=l*2){for(int i=0;i<l;i++){ll u=x[st+i],v=x[st+l+i];if(op==1) x[st+i]=(u+v)%mod,x[st+l+i]=v;else x[st+i]=(u+mod-v)%mod,x[st+l+i]=v;}}} }

XOR

這個和之前的有所不同。

定義

求:ck=∑i⊕?j=kaibjc_k=\sum_{i\operatorname{\oplus}j=k}a_ib_jck?=ij=k?ai?bj?
d(x)d(x)d(x) 為二進制下 xxx 的1的個數的奇偶性(模2的結果)。
有性質:d(i&k)⊕d(j&k)=d((i⊕j)&k)d(i\& k)\oplus d(j\& k)=d((i\oplus j)\& k)d(i&k)d(j&k)=d((ij)&k)。
證明:
由于與運算,只考慮 kkk 為1的那些位。如果某一位 i,ji,ji,j 都是1或0,那么等號兩邊的奇偶性都不改變;如果某一位 i,ji,ji,j 一個是1一個是0,那么等號兩邊的奇偶性都改變;所以等號兩遍的奇偶性始終同步改變,最后就一定是相等的。

設計:
FWT?xor(A)k=∑i(?1)d(i&k)ai\operatorname{FWT}_{xor}(A)_k=\sum_{i} (-1)^{d(i\& k)}a_iFWTxor?(A)k?=i?(?1)d(i&k)ai?
那么還是嘗試逐項相乘:
FWT?xor(A)?FWT?xor(B)=∑k(∑i(?1)d(i&k)ai)×(∑j(?1)d(j&k)bj)\operatorname{FWT}_{xor}(A)*\operatorname{FWT}_{xor}(B)=\sum_k(\sum_{i} (-1)^{d(i\& k)}a_i)\times (\sum_{j} (-1)^{d(j\& k)}b_j)FWTxor?(A)?FWTxor?(B)=k?(i?(?1)d(i&k)ai?)×(j?(?1)d(j&k)bj?)
=∑k∑i,j(?1)d(i&k)+d(j&k)aibj=∑k∑i,j(?1)d(i&k)⊕d(j&k)aibj=\sum_k\sum_{i,j} (-1)^{d(i\& k)+d(j\& k)}a_ib_j=\sum_k\sum_{i,j} (-1)^{d(i\& k)\oplus d(j\& k)}a_ib_j=k?i,j?(?1)d(i&k)+d(j&k)ai?bj?=k?i,j?(?1)d(i&k)d(j&k)ai?bj?
=∑k∑i,j(?1)d((i⊕j)&k)aibj=FWT?xor(C)=\sum_k\sum_{i,j} (-1)^{d((i\oplus j)\& k)}a_ib_j=\operatorname{FWT}_{xor}(C)=k?i,j?(?1)d((ij)&k)ai?bj?=FWTxor?(C)
得證。

變換

還是分治的思想,考慮到增加一位后,只有下標最高位帶1的數貢獻到了下標最高位帶1的位置時,最高位與運算結果為1,1的個數增加一個,奇偶性改變,所有的符號都變為相反。其它的轉移都不變。
也就是:
FWT?xor(A)=(FWT?xor(A0)+FWT?xor(A1),FWT?xor(A0)?FWT?xor(A1))\operatorname{FWT}_{xor}(A)=(\operatorname{FWT}_{xor}(A_0)+\operatorname{FWT}_{xor}(A_1),\operatorname{FWT}_{xor}(A_0)-\operatorname{FWT}_{xor}(A_1))FWTxor?(A)=(FWTxor?(A0?)+FWTxor?(A1?),FWTxor?(A0?)?FWTxor?(A1?))

逆變換

反過來即可。
FWT?xor(A)=(FWT?xor(A0)+FWT?xor(A1)2,FWT?xor(A0)?FWT?xor(A1)2)\operatorname{FWT}_{xor}(A)=(\frac{\operatorname{FWT}_{xor}(A_0)+\operatorname{FWT}_{xor}(A_1)}{2},\frac{\operatorname{FWT}_{xor}(A_0)-\operatorname{FWT}_{xor}(A_1)}{2})FWTxor?(A)=(2FWTxor?(A0?)+FWTxor?(A1?)?,2FWTxor?(A0?)?FWTxor?(A1?)?)

代碼

void Xor(ll *x,int n,int op){for(int l=1;l<n;l<<=1){for(int st=0;st<n;st+=l*2){for(int i=0;i<l;i++){ll u=x[st+i],v=x[st+l+i];if(op==1) x[st+i]=(u+v)%mod,x[st+l+i]=(u+mod-v)%mod;else x[st+i]=(u+v)%mod*499122177%mod,x[st+l+i]=(u+mod-v)%mod*499122177%mod;}}} }

Thanks for reading!

總結

以上是生活随笔為你收集整理的模板:快速莫比乌斯变换(FMT)+快速沃尔什变换(FWT)(多项式)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。