洛谷P4717 【模板】快速沃尔什变换(FWT)
这玩意儿太骚了……
参考了yyb巨佬的
1 //minamoto 2 #include<iostream> 3 #include<cstdio> 4 #define ll long long 5 #define add(x,y) ((x+=y)>=mod?x-=mod:x) 6 using namespace std; 7 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++) 8 char buf[1<<21],*p1=buf,*p2=buf; 9 inline int read(){ 10 #define num ch-'0' 11 char ch;bool flag=0;int res; 12 while(!isdigit(ch=getc())) 13 (ch=='-')&&(flag=true); 14 for(res=num;isdigit(ch=getc());res=res*10+num); 15 (flag)&&(res=-res); 16 #undef num 17 return res; 18 } 19 char sr[1<<21],z[20];int C=-1,Z; 20 inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;} 21 inline void print(int x){ 22 if(C>1<<20)Ot();if(x<0)sr[++C]=45,x=-x; 23 while(z[++Z]=x%10+48,x/=10); 24 while(sr[++C]=z[Z],--Z);sr[++C]=' '; 25 } 26 const int N=(1<<17)+5,mod=998244353,inv=499122177; 27 int n,len,A[N],B[N],R[N]; 28 void FWT_or(int *A,int type){ 29 for(int i=1;i<len;i<<=1) 30 for(int p=i<<1,j=0;j<len;j+=p) 31 for(int k=0;k<i;++k) 32 add(A[i+j+k],type==1?A[j+k]:mod-A[j+k]); 33 } 34 void FWT_and(int *A,int type){ 35 for(int i=1;i<len;i<<=1) 36 for(int p=i<<1,j=0;j<len;j+=p) 37 for(int k=0;k<i;++k) 38 add(A[j+k],type==1?A[i+j+k]:mod-A[i+j+k]); 39 } 40 void FWT_xor(int *A,int type){ 41 for(int i=1;i<len;i<<=1) 42 for(int p=i<<1,j=0;j<len;j+=p) 43 for(int k=0;k<i;++k){ 44 int x=A[j+k],y=A[i+j+k]; 45 A[j+k]=(x+y)%mod,A[i+j+k]=(x+mod-y)%mod; 46 if(type==-1) A[j+k]=1ll*A[j+k]*inv%mod,A[i+j+k]=1ll*A[i+j+k]*inv%mod; 47 } 48 } 49 int main(){ 50 // freopen("testdata.in","r",stdin); 51 n=read(),len=1<<n; 52 for(int i=0;i<len;++i) A[i]=read(); 53 for(int i=0;i<len;++i) B[i]=read(); 54 55 FWT_or(A,1),FWT_or(B,1); 56 for(int i=0;i<len;++i) R[i]=1ll*A[i]*B[i]%mod; 57 FWT_or(A,-1),FWT_or(B,-1),FWT_or(R,-1); 58 for(int i=0;i<len;++i) print(R[i]);sr[++C]='\n'; 59 60 FWT_and(A,1),FWT_and(B,1); 61 for(int i=0;i<len;++i) R[i]=1ll*A[i]*B[i]%mod; 62 FWT_and(A,-1),FWT_and(B,-1),FWT_and(R,-1); 63 for(int i=0;i<len;++i) print(R[i]);sr[++C]='\n'; 64 65 FWT_xor(A,1),FWT_xor(B,1); 66 for(int i=0;i<len;++i) R[i]=1ll*A[i]*B[i]%mod; 67 FWT_xor(R,-1); 68 for(int i=0;i<len;++i) print(R[i]);sr[++C]='\n'; 69 70 Ot(); 71 return 0; 72 }
深深地明白自己的弱小