快速沃尔什变换

题目描述

给定长度为\(2^n\)两个序列\(A,B\),设\(C_i=\sum_{j\oplus k}A_jB_k\)分别当\(\oplus\)是or,and,xor时求出C

输入输出格式

输入格式:

第一行一个数n。 第二行\(2^n\)个数\(A_0..A_{2^n-1}\)第三行\(2^n\)个数\(B_0..B_{2^n-1}\)

输出格式:

三行每行\(2^n\)个数,分别代表\(\oplus\)是or,and,xor时\(C_0..C_{2^n-1}\)的值\(\bmod\ 998244353\)

输入输出样例

输入样例#1:

2

2 4 6 8

1 3 5 7

输出样例#1:

2 22 46 250

88 64 112 56

100 92 68 60

说明

\(n\le 17\)。

题解

2015吕凯风论文和2013王迪论文。

快速莫比乌斯变换

这个只能用来做集合并和与卷积,但是容易理解。



我通过《浅谈容斥原理》找到了另一种形式:

那么通过相同的手段,就可以做集合交卷积。

快速沃尔什变换

这个理论有点复杂,现场推是不可能的,所以背版子吧。

还有类似FFT的实现,不过我反而觉得难写许多。

代码总结

  • and是超集和变换(高维后缀和)。逆变换是超集差变换。

  • or是子集和变换(高维前缀和)。逆变换是子集差变换。

  • xor是蝴蝶变换。逆变换是最后除以长度。

void FAT(poly&a,int dir){ // and -> superset
int lim=a.size(),len=log2(lim);
for(int j=0;j<len;++j)
for(int i=0;i<lim;++i)if(~i>>j&1)
a[i]=add(a[i],dir==1?a[i|1<<j]:mod-a[i|1<<j]);
}
void FOT(poly&a,int dir){ // or -> subset
int lim=a.size(),len=log2(lim);
for(int j=0;j<len;++j)
for(int i=0;i<lim;++i)if(i>>j&1)
a[i]=add(a[i],dir==1?a[i^1<<j]:mod-a[i^1<<j]);
}
void FXT(poly&a,int dir){ // xor
int lim=a.size(),len=log2(lim);
for(int j=0;j<len;++j)
for(int i=0;i<lim;++i)if(~i>>j&1){
int l=a[i],r=a[i|1<<j];
a[i]=add(l,r),a[i|1<<j]=add(l,mod-r);
}
if(dir==-1){
int ilim=fpow(lim,mod-2);
for(int i=0;i<lim;++i) a[i]=mul(a[i],ilim);
}
} int main(){
int len=read<int>(),lim=1<<len;
poly f(lim),g(lim);
for(int i=0;i<lim;++i) read(f[i]);
for(int i=0;i<lim;++i) read(g[i]);
// or
poly a=f,b=g;
FOT(a,1),FOT(b,1);
for(int i=0;i<lim;++i) a[i]=mul(a[i],b[i]);
FOT(a,-1);
for(int i=0;i<lim;++i) printf("%d%c",a[i]," \n"[i==lim-1]);
// and
a=f,b=g;
FAT(a,1),FAT(b,1);
for(int i=0;i<lim;++i) a[i]=mul(a[i],b[i]);
FAT(a,-1);
for(int i=0;i<lim;++i) printf("%d%c",a[i]," \n"[i==lim-1]);
// xor
a=f,b=g;
FXT(a,1),FXT(b,1);
for(int i=0;i<lim;++i) a[i]=mul(a[i],b[i]);
FXT(a,-1);
for(int i=0;i<lim;++i) printf("%d%c",a[i]," \n"[i==lim-1]);
return 0;
}

最新文章

  1. 2-4. Using auto with Functions
  2. SQL一次查出多个字段的COUNT值
  3. git 学习使用总结一(本地操作)
  4. knockout+bootstrap+MVC 登录页实现
  5. WP7应用版本升级的实现方法
  6. leetcode 4 : Median of Two Sorted Arrays 找出两个数组的中位数
  7. 【C#】 开机启动/取消开机启动
  8. html实现层叠加
  9. 笔记本禁用自带键盘攻略-------针对shift默认按下的解决方案
  10. 抓取锁的sql语句-第五次修改
  11. CSS制作出绚丽燃烧的火狐狸
  12. IoC容器Autofac正篇之解析获取(六)
  13. JQuery checkbox全选多次点击后无效解决方法
  14. 我的three.js学习记录(二)
  15. MQ队列堵塞无法读取经验总结
  16. 奇怪吸引子---LorenaMod2
  17. Spyder启动黑屏,终端显示QOpenGLShaderProgram::uniformLocation(qt_Matrix): shader program is not linked QOpenG
  18. Maven 系列 二 :Maven 常用命令,手动创建第一个 Maven 项目
  19. Lucene系列一:搜索引擎核心理论
  20. hdu 5078(2014鞍山现场赛 I题)

热门文章

  1. 2018-2019 ACM-ICPC, Asia Seoul Regional Contest
  2. LA 4287 有相图的强连通分量
  3. python tesseract-ocr 安装包下载地址
  4. SQL学习笔记四之MySQL数据操作
  5. 20145329 《网络对抗技术》 逆向及Bof基础实验
  6. linux实践--字符集
  7. 《Java程序设计》第三章-基础语法
  8. 20145311 《Java程序设计》第4周学习总结
  9. CodeForces 450B Jzzhu and Sequences(矩阵快速幂)题解
  10. 一个轻量级分布式 RPC 框架 — NettyRpc