洛谷P4717 -【模板】快速莫比乌斯/沃尔什变换
与:\(FWT(A)=(FWT(A_0+A_1),FWT(A_1))\)
或:\(FWT(A)=(FWT(A_0),FWT(A_0+A_1))\)
异或:\(FWT(A)=(FWT(A_0+A_1),FWT(A_0-A_1))\)
Code
//【模板】快速莫比乌斯/沃尔什变换 (FMT/FWT)
#include <cstdio>
typedef long long lint;
const int P=998244353;
const lint inv2=499122177;
const int N=1<<20;
int n,a[N],b[N],c[N];
void FWT(int x[],int t1,int t2)
{
for(int i=1;i<(1<<n);i<<=1)
for(int j=0;j<(1<<n);j+=(i<<1))
for(int k=0;k<i;k++)
{
lint p=x[j+k],q=x[i+j+k];
if(t1==0) x[i+j+k]=(q+P+t2*p)%P; //or
else if(t1==1) x[j+k]=(p+P+t2*q)%P; //and
else if(t1==2) //xor
{
x[j+k]=(p+q)%P*(t2<0?inv2:1)%P;
x[i+j+k]=(p+P-q)%P*(t2<0?inv2:1)%P;
}
}
}
int main()
{
scanf("%d",&n);
for(int i=0;i<(1<<n);i++) scanf("%d",&a[i]);
for(int i=0;i<(1<<n);i++) scanf("%d",&b[i]);
for(int t=0;t<3;t++)
{
FWT(a,t,1),FWT(b,t,1);
for(int i=0;i<(1<<n);i++) c[i]=(1LL*a[i]*b[i])%P;
FWT(a,t,-1),FWT(b,t,-1),FWT(c,t,-1);
for(int i=0;i<(1<<n);i++) printf("%d%c",c[i],i<(1<<n)-1?' ':'\n');
}
return 0;
}