Luogu4717 模板快速沃尔什变换(FWT)
Posted gloid
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Luogu4717 模板快速沃尔什变换(FWT)相关的知识,希望对你有一定的参考价值。
https://www.cnblogs.com/RabbitHu/p/9182047.html
完全没有学证明的欲望因为这个实在太好写了而且FFT就算学过也忘得差不多了只会写板子
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<cstdlib> #include<algorithm> using namespace std; #define N (1<<17) #define P 998244353 #define inv2 499122177 int read() { int x=0,f=1;char c=getchar(); while (c<‘0‘||c>‘9‘) {if (c==‘-‘) f=-1;c=getchar();} while (c>=‘0‘&&c<=‘9‘) x=(x<<1)+(x<<3)+(c^48),c=getchar(); return x*f; } int n,a[N],b[N],f[N],g[N]; void OR(int *a,int n,int op) { for (int i=2;i<=n;i<<=1) for (int j=0;j<n;j+=i) for (int k=j;k<j+(i>>1);k++) { int x=a[k],y=a[k+(i>>1)]; if (op==0) a[k]=x,a[k+(i>>1)]=(x+y)%P; else a[k]=x,a[k+(i>>1)]=(y-x+P)%P; } } void AND(int *a,int n,int op) { for (int i=2;i<=n;i<<=1) for (int j=0;j<n;j+=i) for (int k=j;k<j+(i>>1);k++) { int x=a[k],y=a[k+(i>>1)]; if (op==0) a[k]=(x+y)%P,a[k+(i>>1)]=y; else a[k]=(x-y+P)%P,a[k+(i>>1)]=y; } } void XOR(int *a,int n,int op) { for (int i=2;i<=n;i<<=1) for (int j=0;j<n;j+=i) for (int k=j;k<j+(i>>1);k++) { int x=a[k],y=a[k+(i>>1)]; a[k]=(x+y)%P,a[k+(i>>1)]=(x-y+P)%P; if (op==1) a[k]=1ll*a[k]*inv2%P,a[k+(i>>1)]=1ll*a[k+(i>>1)]*inv2%P; } } void FWT(int *a,int *b,int n,int op) { if (op==0) OR(a,n,0),OR(b,n,0); else if (op==1) AND(a,n,0),AND(b,n,0); else if (op==2) XOR(a,n,0),XOR(b,n,0); for (int i=0;i<n;i++) a[i]=1ll*a[i]*b[i]%P; if (op==0) OR(a,n,1); else if (op==1) AND(a,n,1); else if (op==2) XOR(a,n,1); for (int i=0;i<n;i++) printf("%d ",f[i]);cout<<endl; } int main() { freopen("FWT.in","r",stdin); freopen("FWT.out","w",stdout); n=1<<read(); for (int i=0;i<n;i++) a[i]=read(); for (int i=0;i<n;i++) b[i]=read(); memcpy(f,a,sizeof(f));memcpy(g,b,sizeof(g)); FWT(f,g,n,0); memcpy(f,a,sizeof(f));memcpy(g,b,sizeof(g)); FWT(f,g,n,1); memcpy(f,a,sizeof(f));memcpy(g,b,sizeof(g)); FWT(f,g,n,2); return 0; }
以上是关于Luogu4717 模板快速沃尔什变换(FWT)的主要内容,如果未能解决你的问题,请参考以下文章