昨天考試因爲不會fwt而爆炸,因此今天搞了一下fwt……話說這玩意的普及程度已經很高了.
fwt,快速沃爾什變換,能夠用於位運算卷積的優化,是一種線性變換,因此就會有許多好的性質(eg:能夠直接模,能夠修改運算等). & | ^ 的變換定義與方法是基礎,在此基礎上的擴展與運用是重要的地方.
HZOI #1572.宇宙序列
notes:html
這就是形成我考試爆炸的考試題,見Contest Record小程序
UOJ #310.【UNR #2】黎明前的巧克力
notes:數組
感受比較靈活的一道題.首先寫出裸dp,以後會發現答案就是許多數組連續進行fwt,這個時候通過觀察會發現,每一個數組變換後每一個位置上不是-1就是3這個時候咱們能夠對於每一位進行單獨考慮,去算與這一位&以後有奇數位的數的個數,以及與這一位&以後有偶數位的數的個數,咱們能夠用fwt計算這個,而後計算每一位的最後答案,最後再ifwt回去.
思想:
I.感受在fwt裏利用對應位相乘所致使的每一位互相獨立是許多fwt題目中解題的關鍵.
II.在這個題目中觀察性質從而改變問題的思路很巧妙啊.優化
UOJ #267.【清華集訓2016】魔法小程序
notes:htm
就是對於|運算fwt的擴展,看懂題意以後其實就是個加工板子的過程.不過,感受那個數據範圍給的好迷啊,爲何int就能夠呢……不會證實……blog
UOJ #300.【CTSC2017】吉夫特
notes:get
題目比較傻逼,首先能夠寫出n^2裸dp來,而後用Lucas定理能夠證實出,一個組合數爲奇數的充要條件,而後就能夠枚舉子集來dp了,是O(3^18).
實際上這題能夠作得更加優秀.
首先這題能夠進行序列上的分塊,作到O(2^27).
而後這道題還能夠用二進制分塊來動態維護&運算fwt數組,從而作到O(6^9).
思想:用Lucas定理來進行組合數相關的證實(我反正是沒想到這玩意)、分塊思想(序列分塊、二進制分塊).
技巧:枚舉子集是i=(i-1)&x,枚舉父集是i=(i+1)|x.test
UOJ #348.【WC2018】州區劃分
notes:基礎
先寫出O(3^n)的傻逼dp,而後開始優化.
發現轉移是子集卷積的形式,因而考慮進行子集卷積,而後這題就完事了.
子集卷積:
f(i)=sigma [j|k=i,j&k=0] g(j)*h(k);
轉化爲f(c,i)=sigma [j|k=i,|j|+|k|=c] g(j)*h(k)
這個時候咱們原來的子集卷積,就變爲了二維卷積(也就是加法卷積套|運算卷積),顯然第一維卷積能夠直接計算,第二維卷積fwt就能夠了,因而子集卷積的複雜度從O(3^n)優化到了O(n^2*2^n).擴展