快速沃尔变换 FWT
P4717 【模板】快速沃尔什变换
#include<bits/stdc++.h> using namespace std; #define int long long #define sc(x) scanf("%lld",&(x)); #define si signed const int maxn=1<<18+2; int A[maxn]; int B[maxn]; int C[maxn]; #define mod 998244353 #define inv2 ((mod+1)/2) int n; int t; void FWT_or(int *C,int op) { for(int i=1;i<n;i<<=1){ for(int p=i<<1,j=0;j<n;j+=p){ for(int k=0;k<i;k++){ if(op==1)C[i+j+k]=(C[i+j+k]+C[j+k])%mod; if(op==-1)C[i+j+k]=(C[i+j+k]-C[j+k]+mod)%mod; } } } } void FWT_and(int *C,int op) { for(int i=1;i<n;i<<=1){ for(int p=i<<1,j=0;j<n;j+=p){ for(int k=0;k<i;k++){ if(op==1)C[j+k]=(C[i+j+k]+C[j+k])%mod; if(op==-1)C[j+k]=(C[j+k]+mod-C[i+j+k])%mod; } } } } void FWT_xor(int *C,int op) { for(int i=1;i<n;i<<=1){ for(int p=i<<1,j=0;j<n;j+=p){ for(int k=0;k<i;k++){ int x=C[j+k],y=C[i+j+k]; C[j+k]=(x+y)%mod; C[j+k+i]=(x-y+mod)%mod; if(op==-1){ C[j+k]=C[j+k]*inv2%mod; C[j+k+i]=C[j+k+i]*inv2%mod; } } } } } si main() { sc(t); n=(1<<t); for(int i=0;i<n;i++){ sc(A[i]); } for(int i=0;i<n;i++){ sc(B[i]); } FWT_or(A,1);FWT_or(B,1); for(int i=0;i<n;i++){ C[i]=(A[i]*B[i])%mod; } FWT_or(A,-1);FWT_or(B,-1); FWT_or(C,-1); for(int i=0;i<n;i++){ cout<<C[i]<<' '; } cout<<'\n'; FWT_and(A,1);FWT_and(B,1); for(int i=0;i<n;i++){ C[i]=(A[i]*B[i])%mod; } FWT_and(A,-1);FWT_and(B,-1); FWT_and(C,-1); for(int i=0;i<n;i++){ cout<<C[i]<<' '; } cout<<'\n'; FWT_xor(A,1);FWT_xor(B,1); for(int i=0;i<n;i++){ C[i]=(A[i]*B[i])%mod; } FWT_xor(A,-1);FWT_xor(B,-1); FWT_xor(C,-1); for(int i=0;i<n;i++){ cout<<C[i]<<' '; } cout<<'\n'; }