P4717 【模板】快速沃尔什变换
题意:
数据范围
n
≤
17
n\leq 17
n≤17
题解:
存个模板
代码:
#include<bits/stdc++.h>
using namespace std;
const int mod=998244353;
const int N=(1<<17)+9;
int n,a[N],b[N],c[N],lim,ta[N],tb[N];
int poww(int a,int b,int c){
int ans=1,base=a;
while(b){
if(b&1)ans=1ll*ans*base%c;
base=1ll*base*base%c;
b>>=1;
}
return ans;
}
int inv2=poww(2,mod-2,mod);
//int inv2=mod+1>>1;
void fwt_or(int *a,int opt){
for(int i=1;i<lim;i<<=1){
for(int p=i<<1,j=0;j<lim;j+=p)
for(int k=0;k<i;++k)
if(opt==1)a[i+j+k]=(a[j+k]+a[i+j+k])%mod;
else a[i+j+k]=(a[i+j+k]+mod-a[j+k])%mod;
}
}
void fwt_and(int *a,int opt){
for(int i=1;i<lim;i<<=1)
for(int p=i<<1,j=0;j<lim;j+=p)
for(int k=0;k<i;++k)
if(opt==1)a[j+k]=(a[j+k]+a[i+j+k])%mod;
else a[j+k]=(a[j+k]+mod-a[i+j+k])%mod;
}
void fwt_xor(int *a,int opt){
for(int i=1;i<lim;i<<=1)
for(int p=i<<1,j=0;j<lim;j+=p)
for(int k=0;k<i;++k){
int x=a[j+k],y=a[i+j+k];
a[j+k]=(x+y)%mod,a[i+j+k]=(x+mod-y)%mod;
if(opt==-1)a[j+k]=1ll*a[j+k]*inv2%mod,a[i+j+k]=1ll*a[i+j+k]*inv2%mod;
}
}
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>n;lim=1<<n;
for(int i=0;i<lim;i++)cin>>a[i],ta[i]=a[i];
for(int i=0;i<lim;i++)cin>>b[i],tb[i]=b[i];
fwt_or(ta,1),fwt_or(tb,1);
for(int i=0;i<lim;i++)ta[i]=1ll*ta[i]*tb[i]%mod;
fwt_or(ta,-1);
for(int i=0;i<lim;i++)cout<<ta[i]<<" ";
cout<<endl;
for(int i=0;i<lim;i++)ta[i]=a[i],tb[i]=b[i];
fwt_and(ta,1),fwt_and(tb,1);
for(int i=0;i<lim;i++)ta[i]=1ll*ta[i]*tb[i]%mod;
fwt_and(ta,-1);
for(int i=0;i<lim;i++)cout<<ta[i]<<" ";
cout<<endl;
for(int i=0;i<lim;i++)ta[i]=a[i],tb[i]=b[i];
fwt_xor(ta,1),fwt_xor(tb,1);
for(int i=0;i<lim;i++)ta[i]=1ll*ta[i]*tb[i]%mod;
fwt_xor(ta,-1);
for(int i=0;i<lim;i++)cout<<ta[i]<<" ";
cout<<endl;
return 0;
}