P4717 【模板】快速莫比乌斯 / 沃尔什变换 (FMT / FWT)题解

P4717 【模板】快速莫比乌斯 / 沃尔什变换 (FMT / FWT)

题目描述

给定长度为 2n2^n2n 两个序列 A,BA,BA,B,设

Ci=∑j⊕k=iAj×BkC_i=\sum_{j\oplus k = i}A_j \times B_kCi=jk=iAj×Bk

分别当 ⊕\oplus 是 or, and, xor 时求出 CCC

输入格式

第一行,一个整数 nnn
第二行,2n2^n2n 个数 A0,A1,…,A2n−1A_0, A_1, \ldots, A_{2^n-1}A0,A1,,A2n1
第三行,2n2^n2n 个数 B0,B1,…,B2n−1B_0, B_1, \ldots, B_{2^n-1}B0,B1,,B2n1

输出格式

三行,每行 2n2^n2n 个数,分别代表 ⊕\oplus 是 or, and, xor 时 C0,C1,…,C2n−1C_0, C_1, \ldots, C_{2^n-1}C0,C1,,C2n1 的值  mod  998244353\bmod\ 998244353mod 998244353

输入输出样例 #1

输入 #1

2
2 4 6 8
1 3 5 7

输出 #1

2 22 46 250
88 64 112 56
100 92 68 60

说明/提示

1≤n≤171 \le n \le 171n17

思路

模板题,直接写即可。

代码见下

#include<bits/stdc++.h> 
using namespace std;
long long n,m,aa[200005],bb[200005],a[200005],b[200005];
const long long mod=998244353;
void or1(long long *f,long long x){
    for(int o=2,k=1;o<=n;o*=2,k*=2){
        for(int i=0;i<=n-1;i+=o){
            for(int j=0;j<=k-1;j++){
                f[i+j+k]=(f[i+j+k]+f[i+j]*x)%mod;
            }
        }
    }
    return ;
}
void and1(long long *f,long long x){
    for(int o=2,k=1;o<=n;o*=2,k*=2){
        for(int i=0;i<=n-1;i+=o){
            for(int j=0;j<=k-1;j++){
                f[i+j]=(f[i+j]+f[i+j+k]*x)%mod;
            }
        }
    }
    return ;
}
void xor1(long long *f,long long x){
    for(int o=2,k=1;o<=n;o*=2,k*=2){
        for(int i=0;i<=n-1;i+=o){
            for(int j=0;j<=k-1;j++){
                f[i+j]=(f[i+j]+f[i+j+k])%mod;
                f[i+j+k]=(f[i+j]-f[i+j+k]-f[i+j+k]+mod*2)%mod;
                f[i+j]=(f[i+j]*x)%mod;
                f[i+j+k]=(f[i+j+k]*x)%mod;
            }
        }
    }
    return ;
}
int main(){
    cin>>m;
    n=pow(2,m);
    for(int i=0;i<=n-1;i++){
        cin>>aa[i];
    }
    for(int i=0;i<=n-1;i++){
        cin>>bb[i];
    }
    for(int i=0;i<=n-1;i++){
        a[i]=aa[i];
        b[i]=bb[i];
    }
    or1(a,1);
    or1(b,1);
    for(int i=0;i<=n-1;i++){
        a[i]=(a[i]*b[i])%mod;
    }
    or1(a,mod-1);
    for(int i=0;i<=n-1;i++){
        cout<<a[i]<<" ";
    }
    cout<<endl;
    for(int i=0;i<=n-1;i++){
        a[i]=aa[i];
        b[i]=bb[i];
    }
    and1(a,1);
    and1(b,1);
    for(int i=0;i<=n-1;i++){
        a[i]=(a[i]*b[i])%mod;
    }
    and1(a,mod-1);
    for(int i=0;i<=n-1;i++){
        cout<<a[i]<<" ";
    }
    cout<<endl;    
    for(int i=0;i<=n-1;i++){
        a[i]=aa[i];
        b[i]=bb[i];
    }
    xor1(a,1);
    xor1(b,1);
    for(int i=0;i<=n-1;i++){
        a[i]=(a[i]*b[i])%mod;
    }
    xor1(a,mod/2+1);
    for(int i=0;i<=n-1;i++){
        cout<<a[i]<<" ";
    }
    cout<<endl;    
	return 0; 	
}
posted @ 2026-02-06 17:03  bz02_2023f2  阅读(1)  评论(0)    收藏  举报  来源