洛谷4717:【模板】 快速沃尔什变换——题解
https://www.luogu.org/problemnew/show/P4717
攒板子,FWT果然还是像FFT背下来最好。
考试谁会去推啊(滑稽)
丢一份大佬的讲解就跑https://www.cnblogs.com/RabbitHu/p/9182047.html。
#include<cmath> #include<stack> #include<queue> #include<cstdio> #include<cctype> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> using namespace std; typedef long long ll; const int p=998244353; const int inv2=499122177; const int N=1<<17; inline int read(){ int X=0,w=0;char ch=0; while(!isdigit(ch)){w|=ch=='-';ch=getchar();} while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar(); return w?-X:X; } inline void write(int x){ if(x>9)write(x/10); putchar(48+x%10); } inline int add(int x,int y){ x+=y;if(x>=p)x-=p;return x; } inline int sub(int x,int y){ x-=y;if(x<0)x+=p;return x; } void FWT_or(int a[],int n,int on){ for(int i=1;i<n;i<<=1){ for(int j=0;j<n;j+=(i<<1)){ for(int k=0;k<i;k++){ int u=a[j+k],t=a[j+k+i]; a[j+k]=u; if(on==1)a[j+k+i]=add(t,u); else a[j+k+i]=sub(t,u); } } } } void FWT_and(int a[],int n,int on){ for(int i=1;i<n;i<<=1){ for(int j=0;j<n;j+=(i<<1)){ for(int k=0;k<i;k++){ int u=a[j+k],t=a[j+k+i]; if(on==1)a[j+k]=add(u,t); else a[j+k]=sub(u,t); a[j+k+i]=t; } } } } void FWT_xor(int a[],int n,int on){ for(int i=1;i<n;i<<=1){ for(int j=0;j<n;j+=(i<<1)){ for(int k=0;k<i;k++){ int u=a[j+k],t=a[j+k+i]; a[j+k]=add(u,t);a[j+k+i]=sub(u,t); if(on==-1){ a[j+k]=(ll)a[j+k]*inv2%p; a[j+k+i]=(ll)a[j+k+i]*inv2%p; } } } } } int a[N],b[N],c[N],d[N]; int main(){ int n=read(),m=(1<<n); for(int i=0;i<m;i++)a[i]=read(); for(int i=0;i<m;i++)b[i]=read(); memcpy(c,a,sizeof(c)); memcpy(d,b,sizeof(b)); FWT_or(c,m,1);FWT_or(d,m,1); for(int i=0;i<m;i++)c[i]=(ll)c[i]*d[i]%p; FWT_or(c,m,-1); for(int i=0;i<m;i++)write(c[i]),putchar(' '); putchar('\n'); memcpy(c,a,sizeof(c)); memcpy(d,b,sizeof(b)); FWT_and(c,m,1);FWT_and(d,m,1); for(int i=0;i<m;i++)c[i]=(ll)c[i]*d[i]%p; FWT_and(c,m,-1); for(int i=0;i<m;i++)write(c[i]),putchar(' '); putchar('\n'); memcpy(c,a,sizeof(c)); memcpy(d,b,sizeof(b)); FWT_xor(c,m,1);FWT_xor(d,m,1); for(int i=0;i<m;i++)c[i]=(ll)c[i]*d[i]%p; FWT_xor(c,m,-1); for(int i=0;i<m;i++)write(c[i]),putchar(' '); putchar('\n'); return 0; }
+++++++++++++++++++++++++++++++++++++++++++
+本文作者:luyouqi233。 +
+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+
+++++++++++++++++++++++++++++++++++++++++++