Loading

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

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

其解决的问题是对于长度为 \(2^n\) 的数组 \(A[0\sim2^n-1],B[0\sim2^n-1]\),求出数组 \(C\) 使得其满足:

\[C_k=\sum_{i\oplus j=k}A_iB_j \]

其中 \(\oplus\) 是一种位运算,一般为 \(\operatorname{And},\operatorname{Or},\operatorname{Xor}\) 中的一种。

FWT 的思想是对数组 \(A,B\) 进行 FWT 变换使得其变成 \(\operatorname{FWTA},\operatorname{FWTB}\),并满足 \(\operatorname{FWTC}\) 等于 \(\operatorname{FWTA,FWTB}\) 对应点值相乘,即有 \(\operatorname{FWTC_i}=\operatorname{FWTA_i}\times\operatorname{FWTB_i}\)

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

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

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

\[\operatorname{FWTA}_i=\sum_jc(i,j)A_j \]

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

先利用性质 \(\operatorname{FWTC_i}=\operatorname{FWTA_i}\times\operatorname{FWTB_i}\)

代入得对于任意 \(i\) 有:

\[\sum_jc(i,j)A_j\sum_kc(i,k)B_k=\sum_lc(i,l)C_l \]

交换求和顺序:

\[\sum_j\sum_kc(i,j)c(i,k)A_jB_k=\sum_lc(i,l)C_l \]

我们得到了式 \(1\)

再将 \(C_t=\sum\limits_{t_1\oplus t_2=k}A_{t_1}B_{t_2}\) 乘上变换系数:

\[\sum_tc(i,t)C_t=\sum_tc(i,t)\sum_{t_1\oplus t_2=k}A_{t_1}B_{t_2} \]

将右式改为枚举 \(t_1,t_2\),得:

\[\sum_tc(i,t)C_t=\sum_{t_1}\sum_{t_2}c(i,t_1\oplus t_2)A_{t_1}B_{t_2} \]

我们得到了式 \(2\)

\(1\),式 \(2\) 中有共同的 \(\sum\limits_{t}c(i,t)C_t\)(式 \(1\) 中只是名不同,下面联立的结果也是替换变量名后的),故联立可得出:

\[\sum_{t_1}\sum_{t_2}c(i,t_1\oplus t_2)A_{t_1}B_{t_2}=\sum_{t_1}\sum_{t_2}c(i,t_1)c(i,t_2)A_{t_1}B_{t_2} \]

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

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

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

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

我们仍然是考虑式子:

\[\operatorname{FWTA}_i=\sum\limits_jc(i,j)A_j \]

将其分为前后各大小为 \(2^{n-1}\) 的两部分:

\[\operatorname{FWTA}_i=\sum_{j=0}^{2^{n-1}-1}c(i,j)A_j+\sum_{j=2^{n-1}}^{2^n-1}c(i,j)A_j \]

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

\[\operatorname{FWTA}_i=c(i_0,0)\sum_{j=0}^{2^{n-1}-1}c(i',j')A_j+c(i_0,1)\sum_{j=2^{n-1}}^{2^n-1}c(i',j')A_j \]

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

  • 对于 \(i_0=0\)\(\operatorname{FWTA}_i=c(0,0)\operatorname{FWTA'}_i+c(0,1)\operatorname{FWTA''}_i\)

  • 对于 \(i_0=1\)\(\operatorname{FWTA}_i=c(1,0)\operatorname{FWTA'}_i+c(1,1)\operatorname{FWTA''}_i\)

而 FWT 采用倍增的方法,这就导致了在计算长度为 \(2^n\) 的 FWT 数组已经将长度为 \(2^{n-1}\)\(\operatorname{FWTA'}\)\(\operatorname{FWTA''}\) 预先计算出,自此 FWT 过程成功完成。

那么 IFWT 呢?

观察到对于 \(i_0=0\)\(\operatorname{FWTA}_i\) 的计算实际上可以表为矩阵乘法的形式:

\[ \begin{bmatrix} \operatorname{FWTA'}_i & \operatorname{FWTA''}_i \\ \end{bmatrix} \times \begin{bmatrix} c(0,0) & c(0,1) \\ c(1,0) & c(1,1) \end{bmatrix} =\begin{bmatrix} \operatorname{FWTA}_i & \operatorname{FWTA}_{i+2^{n-1}} \\ \end{bmatrix} \]

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

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

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

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

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

\(\operatorname{Or}\)

显然 \(c(i,j)=c^2(i,j)\),故 \(c(i,j)\in\{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\)

我们得到矩阵为:

\[\begin{bmatrix} 1 & 0 \\ 1 & 1 \end{bmatrix} \]

其逆矩阵为:

\[\begin{bmatrix} 1 & 0 \\ -1 & 1 \end{bmatrix} \]

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

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

\(\operatorname{And}\)

\(\operatorname{Or}\) 几乎完全相同的推法。

显然 \(c(i,j)=c^2(i,j)\),故 \(c(i,j)\in\{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\)

我们得到矩阵为:

\[\begin{bmatrix} 1 & 1 \\ 0 & 1 \end{bmatrix} \]

其逆矩阵为:

\[\begin{bmatrix} 1 & -1 \\ 0 & 1 \end{bmatrix} \]

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

\(\operatorname{Xor}\)

首先 \(c(i,0)=c^2(i,0)\),得到 \(c(i,0)=0\operatorname{or}1\)

同时,对于任意 \(j\),有 \(c(i,0)=c^2(i,j)\),由于 \(c(i,j)\) 不可能全为 \(0\)(这样就满足不了对角线成绩不等),故 \(c(i,0)=1,c(i,j)=1\operatorname{or}-1\)

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

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

不妨令 \(c(0,1)=1\)

我们得到矩阵为:

\[\begin{bmatrix} 1 & 1 \\ 1 & -1 \end{bmatrix} \]

其逆矩阵为:

\[\begin{bmatrix} \frac{1}{2} & \frac{1}{2} \\ \frac{1}{2} & -\frac{1}{2} \end{bmatrix} \]

观察到此时 \(c(i,j)=(-1)^{|i\&j|}\),即若 \(i\)\(j\) 交集的大小为奇数,\(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 是一种线性变换,所以其满足性质 \(\operatorname{FMT}(A+B)=\operatorname{FMT}(A)+\operatorname{FMT}(B)\)

由此可得,数乘其同样满足 \(\operatorname{FMT}(kA)=k\operatorname{FMT}(A)\)

posted @ 2023-01-16 16:48  lstqwq  阅读(179)  评论(0编辑  收藏  举报