【moban】快速沃尔什变换(FWT)模板

到广州了,好热,阳光好刺眼orz,飞机上颓过去了,趁着等车时间看了看原来一直没看懂的fwt,发现还挺好理解的orz 感性理解一下,具体主要是看的yyb的博客 yyb's fwt DFT or $(x_0,x_1)\rightarrow (x_0,x_0+x_1) $ and $(x_0,x_1)\rightarrow (x_0+x_1,x_1) $ xor 唯一一个无法直接感性理解的,背下来,先加后减。 $(x_0,x_1)\rightarrow (x_0+x_1,x_0-x_1) $ IDFT 前面背下来,这里就是逆运算了 or $(x_0,x_1)\rightarrow(x_0,x_1-x_0)$ and $(x_0,x_1)\rightarrow(x_0-x_1,x_1)$ xor $(x_0,x_1)\rightarrow((x_0+x_1)/2,(x_0-x_1)/2)$ 变换之后就可以进行卷积运算了,和法法塔的方式很像。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>

using namespace std;

void fwtor(int *a,int s,int dft) {//(a0,a0+a1)
    for(int st=1;st<s;st<<=1) {
        for(int i=0;i<s;i+=(st<<1)) {
            for(int j=i;j<i+st;j++) {
                if(dft==1) a[j+st] = add(a[j+st],a[j]);
                else a[j+st] = sub(a[j+st],a[j]);
            }
        }
    }
}
void fwtand(int *a,int s,int dft) { //(a0+a1,a1)
    for(int st=1;st<s;st<<=1) {
        for(int i=0;i<s;i+=(st<<1)) {
            for(int j=i;j<i+st;j++) {
                if(dft==1) a[j] = add(a[j].a[j+st]);
                else a[j] = sub(a[j],a[j+st]);
            }
        }
    }
}
void fwtxor(int *a,int s,int dft) {//(a0+a1,a0-a1)
    for(int st=1;st<s;st<<=1) {
        for(int i=0;i<s;i+=(st<<1)) {
            for(int j=i;j<i+st;j++) {
                int x = a[j]; int y = a[j+st];
                a[j] = add(x,y); a[j+st] = sub(x,y);
                if(dft==-1) a[j]=mul(a[j],inv2),a[j+st]=mul(a[j+st],inv2);
            }
        }
    }
}
posted @ 2019-01-24 15:23  Newuser233  阅读(10)  评论(0)    收藏  举报