您的位置:首页 > 其它

洛谷4717:【模板】 快速沃尔什变换——题解

2018-06-24 11:28 239 查看

https://www.luogu.org/problemnew/show/P4717

攒板子,FWT果然还是像FFT背下来最好。

考试谁会去推啊(滑稽)

丢一份大佬的讲解就跑https://www.geek-share.com/detail/2739945140.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
,b
,c
,d
;
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/+

+++++++++++++++++++++++++++++++++++++++++++

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: