云计算百科
云计算领域专业知识百科平台

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<=n1;i+=o){
for(int j=0;j<=k1;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<=n1;i+=o){
for(int j=0;j<=k1;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<=n1;i+=o){
for(int j=0;j<=k1;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<=n1;i++){
cin>>aa[i];
}
for(int i=0;i<=n1;i++){
cin>>bb[i];
}
for(int i=0;i<=n1;i++){
a[i]=aa[i];
b[i]=bb[i];
}
or1(a,1);
or1(b,1);
for(int i=0;i<=n1;i++){
a[i]=(a[i]*b[i])%mod;
}
or1(a,mod1);
for(int i=0;i<=n1;i++){
cout<<a[i]<<" ";
}
cout<<endl;
for(int i=0;i<=n1;i++){
a[i]=aa[i];
b[i]=bb[i];
}
and1(a,1);
and1(b,1);
for(int i=0;i<=n1;i++){
a[i]=(a[i]*b[i])%mod;
}
and1(a,mod1);
for(int i=0;i<=n1;i++){
cout<<a[i]<<" ";
}
cout<<endl;
for(int i=0;i<=n1;i++){
a[i]=aa[i];
b[i]=bb[i];
}
xor1(a,1);
xor1(b,1);
for(int i=0;i<=n1;i++){
a[i]=(a[i]*b[i])%mod;
}
xor1(a,mod/2+1);
for(int i=0;i<=n1;i++){
cout<<a[i]<<" ";
}
cout<<endl;
return 0;
}

赞(0)
未经允许不得转载:网硕互联帮助中心 » P4717 【模板】快速莫比乌斯 / 沃尔什变换 (FMT / FWT)题解
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!