快速沃尔什变换

题目描述

给定长度为\(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;
}

LG4717 【模板】快速沃尔什变换的更多相关文章

  1. 洛谷.4717.[模板]快速沃尔什变换(FWT)

    题目链接 https://www.mina.moe/archives/7598 //285ms 3.53MB #include <cstdio> #include <cctype&g ...

  2. Fast Walsh-Hadamard Transform——快速沃尔什变换

    模板题: 给定$n = 2^k$和两个序列$A_{0..n-1}$, $B_{0..n-1}$,求 $$C_i = \sum_{j \oplus k = i} A_j B_k$$ 其中$\oplus$ ...

  3. [学习笔记]FWT——快速沃尔什变换

    解决涉及子集配凑的卷积问题 一.介绍 1.基本用法 FWT快速沃尔什变换学习笔记 就是解决一类问题: $f[k]=\sum_{i\oplus j=k}a[i]*b[j]$ 基本思想和FFT类似. 首先 ...

  4. 快速沃尔什变换(FWT)学习笔记

    概述 FWT的大体思路就是把要求的 C(x)=A(x)×B(x)  即 \( c[i]=\sum\limits_{j?k=i} (a[j]*b[k]) \) 变换成这样的:\( c^{'}[i]=a^ ...

  5. 初学FWT(快速沃尔什变换) 一点心得

    FWT能解决什么 有的时候我们会遇到要求一类卷积,如下: Ci=∑j⊕k=iAj∗Bk\large C_i=\sum_{j⊕k=i}A_j*B_kCi​=j⊕k=i∑​Aj​∗Bk​此处乘号为普通乘法 ...

  6. JS组件系列——BootstrapTable+KnockoutJS实现增删改查解决方案(四):自定义T4模板快速生成页面

    前言:上篇介绍了下ko增删改查的封装,确实节省了大量的js代码.博主是一个喜欢偷懒的人,总觉得这些基础的增删改查效果能不能通过一个什么工具直接生成页面效果,啥代码都不用写了,那该多爽.于是研究了下T4 ...

  7. 关于快速沃尔什变换(FWT)的一点学习和思考

    最近在学FWT,抽点时间出来把这个算法总结一下. 快速沃尔什变换(Fast Walsh-Hadamard Transform),简称FWT.是快速完成集合卷积运算的一种算法. 主要功能是求:,其中为集 ...

  8. FWT快速沃尔什变换学习笔记

    FWT快速沃尔什变换学习笔记 1.FWT用来干啥啊 回忆一下多项式的卷积\(C_k=\sum_{i+j=k}A_i*B_j\) 我们可以用\(FFT\)来做. 甚至在一些特殊情况下,我们\(C_k=\ ...

  9. 一个数学不好的菜鸡的快速沃尔什变换(FWT)学习笔记

    一个数学不好的菜鸡的快速沃尔什变换(FWT)学习笔记 曾经某个下午我以为我会了FWT,结果现在一丁点也想不起来了--看来"学"完新东西不经常做题不写博客,就白学了 = = 我没啥智 ...

随机推荐

  1. Ubuntu软件包管理器

    Ubuntu软件包管理 Ubuntu下对软件管理工具有:apt,dpkg,tasksel,aptitude等,我们常用的就是前三个工具.下面就介绍这三个工具的用法. dpkg 在Linux发展之初,安 ...

  2. Git冲突:commit your changes or stash them before you can merge. 解决办法

    用git pull来更新代码的时候,遇到了下面的问题: 1 2 3 4 error: Your local changes to the following files would be overwr ...

  3. Python笔记 #12# Dictionary & Pandas: Object Creation

    Document of Dictionaries 10 Minutes to pandas tutorialspoint import pandas as pd data = [['Alex',10] ...

  4. zabbix-2.4.7环境部署与初始化安装

    一.zabbix简介: zabbix的特点: - 安装与配置简单,学习成本低 - 支持多语言(包括中文) - 免费开源 - 自动发现服务器与网络设备 - 分布式监视以及WEB集中管理功能 - 可以无a ...

  5. Linux内核分析06

    进程的描述和进程的创建 一,进程的描述 进程控制块PCB——task_struct (进程描述符),为了管理进程,内核必须对每个进程进行清晰的描述,进程描述符提供了内核所需了解的进程信息. struc ...

  6. Windows10下用Anaconda3安装TensorFlow教程【转】

    本文转载自:https://www.cnblogs.com/HongjianChen/p/8385547.html 1. 安装好Anaconda3版本 (1) 注:可以发现最新版本是Anaconda5 ...

  7. linux下递归删除指定后缀名的文件

    以删除当前目录到所有子目录下的后缀名为rej的文件为例: find . -name "*.rej" |xargs rm -f

  8. python 计算字典value值的和

    my_dict = {,,} print(sum(my_dict.values()))

  9. 【Python】解决测试依赖之 Mock模块的基本使用

    什么是mock? Mock,顾名思义,模拟,在我们日常生活中或者影视作品中见得最多的可能就是预备飞行员的模拟训练,印象比较深的是电影<萨利机长>中的模拟器,经过几千次模拟,人们得出机长萨利 ...

  10. 朴素贝叶斯 Naive Bayes

    2017-12-15 19:08:50 朴素贝叶斯分类器是一种典型的监督学习的算法,其英文是Naive Bayes.所谓Naive,就是天真的意思,当然这里翻译为朴素显得更学术化. 其核心思想就是利用 ...