@算法 - 2@ 位运算卷积 —— FWT

目录


@0 - 参考资料@

yyb 的讲解
popoqqq 的讲解

@1 - 异或卷积概念及性质@

现在已知两个 n 维的向量 \(A=(a_0,a_1,...,a_{n-1}),B=(b_0,b_1,...,b_{n-1})\)。定义异或卷积式:

\[A\oplus B=(\sum_{i\oplus j=0}a_i*b_j,\sum_{i\oplus j=1}a_i*b_j,\dots,\sum_{i\oplus j=n-1}a_i*b_j)\]

定义加法 \(A\pm B=(a_0\pm b_0,a_1\pm b_1,...,a_{n-1}\pm b_{n-1})\)
定义乘积 \(A*B=(a_0*b_0,a_1*b_1,...,a_{n-1}*b_{n-1})\)

定义\(A_0=(a_0,a_1,...a_{n/2-1}),A_1=(a_{n/2},a_{n/2+1},...,a_{n-1})\),则有 \(A=(A_0,A_1)\)。可以把 \(A_0,A_1\) 理解为向量 \(A\) 的前半部分与后半部分,也可以理解为 \(A\) 中二进制最高位为 0 的部分与二进制最高位为 1 的部分。

异或卷积有着良好的递归性质:

\[A\oplus B=(A_0\oplus B_0+A_1\oplus B_1,A_1\oplus B_0+A_0\oplus B_1)\]

怎么理解呢?根据我刚刚说的 \(A_0,A_1\) 的定义,讨论最高位为 0 或 1 就可以得到如上的式子。

这些运算有以下几个性质。
(1)\(A\oplus B=B\oplus A,A+B=B+A\)(交换律)
(2)\(A\oplus B\oplus C=A\oplus (B\oplus C),A+B+C=A+(B+C)\)(结合律)
(3)\(A\oplus (B+C)=A\oplus B+A\oplus C\)(分配律)
证明可以根据定义,拆 \(\sum\) 得到。

@2 - 快速沃尔什正变换(异或)@

回想我们的加法卷积 \(C_k=\sum_{i+j=k}a_i*b_j\),可以用 FFT 高效解决。
我们根据 FFT 的优化思路,来得到异或卷积的高效算法 FWT。

在搞 FFT 的时候,我们是先把原多项式 \(A(x)\) 由系数表示转为点值表示,再直接逐个相乘,最后由点值表示转回成系数表示。
将系数表示的多项式抽象成一个向量 \(A=(a_0,a_1,...,a_{n-1})\)
将点值表示的多项式也抽象成一个向量 \(A'=(a'_0,a'_1,...,a'_{n-1})\),其中\(a'_i=A(w_n^i)\)
则 FFT 的优化思路就可以抽象出来:将原向量\(A\)转化为新向量\(A'\),使原向量的卷积\(A\oplus B\)对应着新向量的乘积\(A'*B'\),最后把乘积转化为卷积。

我们定义一个函数 \(FWT(A) = A'\),一个定义域和值域都为向量的函数,使得 \(FWT(A\oplus B)=FWT(A)*FWT(B)\)。再定义它的反函数 \(IFWT(A') = A\)
则我们的 FFT 相当于选用了一个特殊的 \(FWT\) 函数,可以让我们快速求解\(FWT(A),IFWT(A')\)

对于异或卷积而言,我们构造性地选取 \(FWT\)
定义异或卷积的 \(FWT\) 函数为:

\[FWT(A)=\begin{cases} (FWT(A_0)+FWT(A_1),FWT(A_0)-FWT(A_1)) & (n>0)\\ A & (n=0)\end{cases}\]

【敲黑板,划重点,这个必考】
我们来验证一下这玩意具有上面那个性质。

性质(1):\(FWT(A+B)=FWT(A)+FWT(B)\)
证明:\(FWT(A+B)\) 中的每一项都是线性组合,故满足分配律。

性质(2):\(FWT(A\oplus B)=FWT(A)*FWT(B)\)
证明:数学归纳法。【集中注意力!!!】
当 n = 1 时,显然成立。
假设对于 k <= n-1 结论成立,则:

\[\begin{aligned} FWT(A\oplus B)&=FWT((A_0\oplus B_0+A_1\oplus B_1,A_1\oplus B_0+A_0\oplus B_1))&\\ &=(FWT(A_0\oplus B_0+A_1\oplus B_1)+FWT(A_1\oplus B_0+A_0\oplus B_1),FWT(A_0\oplus B_0+A_1\oplus B_1)-FWT(A_1\oplus B_0+A_0\oplus B_1))&\\ &=(FWT(A_0\oplus B_0+A_1\oplus B_1+A_1\oplus B_0+A_0\oplus B_1),FWT(A_0\oplus B_0+A_1\oplus B_1-A_1\oplus B_0-A_0\oplus B_1))&\\ &=(FWT((A_0+A_1)\oplus (B_0+B_1)),FWT((A_0-A_1)\oplus (B_0-B_1))&\\ &=(FWT(A_0+A_1)*FWT(B_0+B_1),FWT(A_0-A_1)*FWT(B_0-B_1))&\\ &=(FWT(A_0+A_1),FWT(A_0-A_1))*(FWT(B_0+B_1),FWT(B_0-B_1))&\\ &=FWT(A)*FWT(B) \end{aligned}\]

稍微分析我们每个等号都用了哪些性质。
第一个:用了异或卷积本身的递归性。
第二个:用了 FWT 的定义。
第三个:用了性质 \(FWT(A+B)=FWT(A)+FWT(B)\)
第四个:用了因式分解。
第五个:用了我们数学归纳法的归纳前提。
第六个:用了一个恒等变换(类因式分解),可以验证等式左右两边是相等的。
第七个:逆用了 FWT 的定义。
然后得证我们的结论。

……
只能说很壮观。当初想出来这玩意儿的人真的是不容易。
所以我选择直接背定义。

根据 FWT 的定义,我们可以进行迭代求解。时间复杂度与 FFT 相同,为O(nlog n)。

@3 - 快速沃尔什逆变换(异或)@

好了,正变换搞定了,我们可以写 FWT 了……
稍等。好像还差些什么。
……

好的我们来看看逆变换怎么弄。
由定义可得:\(FWT(A)=(FWT(A_0)+FWT(A_1),FWT(A_0)-FWT(A_1))=A'\)
因此有\(\begin{cases} A'_0=FWT(A_0)+FWT(A_1)&\\ A'_1=FWT(A_0)-FWT(A_1) \end{cases}\)

解一下这个二元方程组就可得:\(\begin{cases} FWT(A_0)=\frac{A'_0+A'_1}{2}&\\ FWT(A_1)=\frac{A'_0-A'_1}{2} \end{cases}\)

两边同时进行逆变换可以得到:\(\begin{cases} A_0=IFWT(\frac{A'_0+A'_1}{2})&\\ A_1=IFWT(\frac{A'_0-A'_1}{2}) \end{cases}\)

所以:\(IFWT(A')=A=(A_0,A_1)=(IFWT(\frac{A'_0+A'_1}{2}),IFWT(\frac{A'_0-A'_1}{2}))\)

简化一下,加上边界: \[IFWT(A)=\begin{cases} (IFWT(\frac{A'_0+A'_1}{2}),IFWT(\frac{A'_0-A'_1}{2})) & (n>0)\\ A & (n=0)\end{cases}\]

因此,我们也可以在 O(nlog n) 的时间复杂度内实现逆变换。

@4 - 与卷积、或卷积@

要知道二进制的运算可不止异或。

定义与卷积,或卷积如下:

\[A|B=(\sum_{i|j=0}a_i*b_j,\sum_{i|j=1}a_i*b_j,\dots,\sum_{i|j=n-1}a_i*b_j)\\ A\&B=(\sum_{i\&j=0}a_i*b_j,\sum_{i\&j=1}a_i*b_j,\dots,\sum_{i\&j=n-1}a_i*b_j)\]

我们直接给出与卷积,或卷积的 FWT 与 IFWT 的表达式。
如果想要证明可以自行参照异或的证明思路进行证明 (或者直接背)

或卷积:
\[FWT(A)=\begin{cases} (FWT(A_0),FWT(A_1)+FWT(A_0)) & (n>0)\\ A & (n=0)\end{cases}\\ IFWT(A)=\begin{cases} (IFWT(A_0),IFWT(A_1)-IFWT(A_0)) & (n>0)\\ A & (n=0)\end{cases} \]

与卷积:
\[FWT(A)=\begin{cases} (FWT(A_0)+FWT(A_1),FWT(A_1)) & (n>0)\\ A & (n=0)\end{cases}\\ IFWT(A)=\begin{cases} (IFWT(A_0)-IFWT(A_1),IFWT(A_1)) & (n>0)\\ A & (n=0)\end{cases} \]

@5 - 参考代码实现@

本代码为 洛谷P4717 的 AC 代码。

#include<cstdio>
const int MOD = 998244353;
const int INV = (998244353 + 1)/2;
const int MAXN = (1<<17);
void fwt_or(int *a, int n, int type) {
    for(int s=2;s<=n;s<<=1) {
        int t = (s>>1);
        for(int i=0;i<n;i+=s) {
            for(int j=0;j<t;j++) {
                int x = a[i+j], y = a[i+j+t];
                a[i+j] = (type == -1) ? x : x;
                a[i+j+t] = (type == -1) ? (y + MOD - x)%MOD : (y + x)%MOD;
            }
        }
    }
}
void fwt_and(int *a, int n, int type) {
    for(int s=2;s<=n;s<<=1) {
        int t = (s>>1);
        for(int i=0;i<n;i+=s) {
            for(int j=0;j<t;j++) {
                int x = a[i+j], y = a[i+j+t];
                a[i+j] = (type == -1) ? (x + MOD - y)%MOD : (x + y)%MOD;
                a[i+j+t] = (type == -1) ? y : y;
            }
        }
    }
}
void fwt_xor(int *a, int n, int type) {
    for(int s=2;s<=n;s<<=1) {
        int t = (s>>1);
        for(int i=0;i<n;i+=s) {
            for(int j=0;j<t;j++) {
                int x = a[i+j], y = a[i+j+t];
                a[i+j] = (type == -1) ? 1LL*(x + y)%MOD*INV%MOD : (x + y)%MOD;
                a[i+j+t] = (type == -1) ? 1LL*(x + MOD - y)%MOD*INV%MOD : (x + MOD - y)%MOD;
            }
        }
    }
}
int A[MAXN + 5], B[MAXN + 5], C[MAXN + 5];
int main() {
    int N; scanf("%d", &N); N = (1<<N);
    for(int i=0;i<N;i++)
        scanf("%d", &A[i]);
    for(int i=0;i<N;i++)
        scanf("%d", &B[i]);

    fwt_or(A, N, 1); fwt_or(B, N, 1);
    for(int i=0;i<N;i++)
        C[i] = 1LL*A[i]*B[i]%MOD;
    fwt_or(A, N, -1); fwt_or(B, N, -1); fwt_or(C, N, -1);
    for(int i=0;i<N;i++)
        printf("%d ", C[i]);
    puts("");

    fwt_and(A, N, 1); fwt_and(B, N, 1);
    for(int i=0;i<N;i++)
        C[i] = 1LL*A[i]*B[i]%MOD;
    fwt_and(A, N, -1); fwt_and(B, N, -1); fwt_and(C, N, -1);
    for(int i=0;i<N;i++)
        printf("%d ", C[i]);
    puts("");

    fwt_xor(A, N, 1); fwt_xor(B, N, 1);
    for(int i=0;i<N;i++)
        C[i] = 1LL*A[i]*B[i]%MOD;
    fwt_xor(A, N, -1); fwt_xor(B, N, -1); fwt_xor(C, N, -1);
    for(int i=0;i<N;i++)
        printf("%d ", C[i]);
    puts("");
}

@6 - 例题与应用@

和 FFT 一样,留坑,待填。

猜你喜欢

转载自www.cnblogs.com/Tiw-Air-OAO/p/10165222.html
FWT