【理论】快速沃尔什变换(FWT)学习笔记

FWT 处理的是位运算卷积问题。

其解决的问题是对于长度为 2n 的数组 A[02n1],B[02n1],求出数组 C 使得其满足:

Ck=ij=kAiBj

其中 是一种位运算,一般为 And,Or,Xor 中的一种。

FWT 的思想是对数组 A,B 进行 FWT 变换使得其变成 FWTA,FWTB,并满足 FWTC 等于 FWTA,FWTB 对应点值相乘,即有 FWTCi=FWTAi×FWTBi

借此求得了 FWTC 之后,我们对其进行 IFWT 变换(即逆 FWT 变换)便可以成功求得 C 数组。

接下来我们来进行具体讲解:

首先,我们要将 A 数组转化为 FWTA,那么我们不妨设变换系数 c(i,j) 使得:

FWTAi=jc(i,j)Aj

我们考虑推 c(i,j) 的一些性质。

先利用性质 FWTCi=FWTAi×FWTBi

代入得对于任意 i 有:

jc(i,j)Ajkc(i,k)Bk=lc(i,l)Cl

交换求和顺序:

jkc(i,j)c(i,k)AjBk=lc(i,l)Cl

我们得到了式 1

再将 Ct=t1t2=kAt1Bt2 乘上变换系数:

tc(i,t)Ct=tc(i,t)t1t2=kAt1Bt2

将右式改为枚举 t1,t2,得:

tc(i,t)Ct=t1t2c(i,t1t2)At1Bt2

我们得到了式 2

1,式 2 中有共同的 tc(i,t)Ct(式 1 中只是名不同,下面联立的结果也是替换变量名后的),故联立可得出:

t1t2c(i,t1t2)At1Bt2=t1t2c(i,t1)c(i,t2)At1Bt2

据此,我们可以得到一个关于变换系数的一个重量级结论: c(i,j)c(i,k)=c(i,jk)

不难发现由于其性质,实际上我们可以按位考虑 c(i,j),即设 ipi 二进制的第 p 位,那么实际上有 c(i,j)=pc(ip,jp),证明非常容易,在此不作过多解释。

通过按位考虑,我们原先要推出的变换系数 c(i,j) 转化为了推出 c(0,0),c(0,1),c(1,0),c(1,1) 四个值,这毫无疑问将问题变得轻松了很多。

我们将变换系数求出来了,下一步呢?如何通过变换系数求出一个数组 A 对应的 FWTA 呢?

我们仍然是考虑式子:

FWTAi=jc(i,j)Aj

将其分为前后各大小为 2n1 的两部分:

FWTAi=j=02n11c(i,j)Aj+j=2n12n1c(i,j)Aj

考虑分为两部分的好处是什么,很显然对于前一部分 j[0,2n11],最高位 j0=0,而对于后一部分 j[2n1,2n1],最高位 j0=1,可以发现,分为两部分使得二进制最高位确定了!那么根据按位思想,我们把 i,j 的最高位全部抛开变成 i,j,根据按位显然有 c(i,j)=c(i0,j0)c(i,j),那么原式就变成了:

FWTAi=c(i0,0)j=02n11c(i,j)Aj+c(i0,1)j=2n12n1c(i,j)Aj

考虑将下标首位为 0 的子数组记作 A,下标首位为 1 的子数组记作 A,那么显然:

  • 对于 i0=0FWTAi=c(0,0)FWTAi+c(0,1)FWTAi

  • 对于 i0=1FWTAi=c(1,0)FWTAi+c(1,1)FWTAi

而 FWT 采用倍增的方法,这就导致了在计算长度为 2n 的 FWT 数组已经将长度为 2n1FWTAFWTA 预先计算出,自此 FWT 过程成功完成。

那么 IFWT 呢?

观察到对于 i0=0FWTAi 的计算实际上可以表为矩阵乘法的形式:

[FWTAiFWTAi]×[c(0,0)c(0,1)c(1,0)c(1,1)]=[FWTAiFWTAi+2n1]

那么不难发现 IFWT 只需要该矩阵求逆后再做一遍 FWT 即可。

同时这也对 c(i,j) 的构造增加了要求,即对应矩阵的逆必须存在(如果这条不要求显然可以构造 c(i,j)=0)。

我们回忆一下线性代数的知识,若二阶方阵的逆存在那么便等价于 c(0,0)c(1,1)c(0,1)c(1,0),这变成了我们构造的限制。

好的那么 FWT 以及 IFWT 的过程就结束了,我们现在要对 And,Or,Xor 推导出 c(i,j)

(另外一个利用的性质是 c(i,j)c(i,k)=c(i,jk)

Or

显然 c(i,j)=c2(i,j),故 c(i,j){0,1}

同时有 c(i,1)=c(i,0)c(i,1),故 c(i,0)=0,c(i,1)=1 不可能。

因为矩阵对角线乘积不等,所以 c(i,0)=c(i,1)=0 不可能,可得 c(i,0) 必须为 1

c(0,0)=c(1,0)=1,为了满足矩阵对角线成绩不等,显然 c(0,1)c(1,1) 中恰有一个为 1

不妨令 c(1,1)=1

我们得到矩阵为:

[1011]

其逆矩阵为:

[1011]

观察到此时 c(i,j)=[i&j=j],即 c(i,j)1 当且仅当 ji 的子集。

(逆矩阵可手动高斯消元得到,详见【模板】矩阵求逆

And

Or 几乎完全相同的推法。

显然 c(i,j)=c2(i,j),故 c(i,j){0,1}

同时有 c(i,0)=c(i,0)c(i,1),故 c(i,0)=1,c(i,1)=0 不可能。

因为矩阵对角线乘积不等,所以 c(i,0)=c(i,1)=0 不可能,可得 c(i,1) 必须为 1

c(0,1)=c(1,1)=1,为了满足矩阵对角线成绩不等,显然 c(0,0)c(1,0) 中恰有一个为 1

不妨令 c(0,0)=1

我们得到矩阵为:

[1101]

其逆矩阵为:

[1101]

观察到此时 c(i,j)=[i&j=i],即 c(i,j)1 当且仅当 ij 的子集。

Xor

首先 c(i,0)=c2(i,0),得到 c(i,0)=0or1

同时,对于任意 j,有 c(i,0)=c2(i,j),由于 c(i,j) 不可能全为 0(这样就满足不了对角线成绩不等),故 c(i,0)=1,c(i,j)=1or1

c(0,0)=c(1,0)=1

因为矩阵对角线乘积不等,所以 c(0,1),c(1,1) 中必须恰一个为 1 一个为 1

不妨令 c(0,1)=1

我们得到矩阵为:

[1111]

其逆矩阵为:

[12121212]

观察到此时 c(i,j)=(1)|i&j|,即若 ij 交集的大小为奇数,c(i,j)=1,反之则有 c(i,j)=1

代码
void FWT(ll *f){
    for(int len=1;len<=(1<<(n-1));len<<=1){
        for(int i=0;i<(1<<n);i+=(len<<1)){
            rep(j,i,i+len-1){
                ll tmp=f[j];
                f[j]=c[0][0]*f[j]+c[0][1]*f[j+len];
                f[j+len]=c[1][0]*tmp+c[1][1]*f[j+len];
                f[j]%=mod;
                f[j+len]%=mod;
            }
        }
    }
    return;
}
void calc(ll tp){
    rep(i,0,(1<<n)-1){
        a[i]=A[i];
        b[i]=B[i];
    }
    if(tp==1){
        c[0][0]=c[1][1]=c[1][0]=1;
        c[0][1]=0;
    }
    if(tp==2){
        c[0][0]=c[0][1]=c[1][1]=1;
        c[1][0]=0;
    }
    if(tp==3){
        c[0][0]=c[0][1]=c[1][0]=1;
        c[1][1]=-1;
    }
    FWT(a);
    FWT(b);
    rep(i,0,(1<<n)-1) C[i]=a[i]*b[i]%mod;
    if(tp==1){
        c[0][0]=c[1][1]=1;
        c[0][1]=0;
        c[1][0]=-1;
    }
    if(tp==2){
        c[0][0]=c[1][1]=1;
        c[0][1]=-1;
        c[1][0]=0;
    }
    if(tp==3){
        c[0][0]=c[0][1]=c[1][0]=inv(2);
        c[1][1]=-c[0][0];
    }
    FWT(C);
    rep(i,0,(1<<n)-1) C[i]=(C[i]+mod)%mod;
}

FWT 的性质:

FWT 是一种线性变换,所以其满足性质 FMT(A+B)=FMT(A)+FMT(B)

由此可得,数乘其同样满足 FMT(kA)=kFMT(A)

posted @   lstqwq  阅读(256)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App
点击右上角即可分享
微信分享提示
主题色彩