算法学习笔记(45): 快速沃尔什变换 FWT
遗憾的是 math
里面一直没有很好的讲这个东西……所以这次细致说说。
FWT 的本质
类似于多项式卷积中,利用 ntt
变换使得卷积 \(\to\) 点乘,fwt
也是类似的应用。
定义某种位运算 \(\oplus\),那么 fwt
处理的位运算卷积形如:
\]
那么我们需要构造出一种变换,使得:
\]
暂时我们还不得而知如何变换,考虑设 \(c(i, j)\) 表示变换系数,那么有:
\]
那么对应的点积:
\]
根据卷积定义:
\]
对比:
\]
我们可以得知:
\]
这个等式便是 fwt
的核心。
另外,考虑到位运算每一位是独立的,那么 \(c(x, y)\) 非常重要的性质是可以按位考虑。也就是说:
\]
其中 \(i_k\) 表示 \(i\) 的第 \(k\) 位。
那么我们只需要构造出 \(c(0/1, 0/1)\) 即可。
不妨假设我们已经构造出了 \(c\),那么怎么求解呢?
类似 ntt
的考虑,分治:
\]
将最高位拆出来,分别记为 \(i', j'\):
\]
于是分半之后:
\]
于是可以 \(O(n)\) 的合并两个规模减半的东西了,于是总复杂度 \(O(w 2^w)\),其中 \(w\) 是位数。
对于逆变换,将 \(c\) 求个逆,变换回去即可。
FWT 的构造
现在我们对于 \(\texttt{or, and, xor}\) 尝试构造其 \(c\) 矩阵。
\(\texttt{or}\)
首先,注意到 \(c(0, 0) c(0, 0) = c(0, 0 | 0)\),于是 \(c(0, 0) = 0/1\)。
同理,不难得出 \(c(0/1, 0/1) \in \{0, 1\}\)。
考虑 \(c(0, 0) c(0, 1) = c(0, 1)\) 可以得出 \(c(0, 0) = c(0, 1) = 1\) 或者 \(c(0, 1) = 0\)。
同理考虑 \(c(1, 0) c(1, 1) = c(1, 1)\) 也可以知道 \(c(1, 1) = 0\) 或者 \(c(1, 0) = c(1, 1) = 1\)。
注意到需要构造出的矩阵有逆,那么只能是:
1 & 1 \\ 1 & 0
\end{bmatrix} \text{或者}
\begin{bmatrix}
1 & 0 \\ 1 & 1
\end{bmatrix}
\]
值得注意的是,第二种矩阵 \(c(i, j)\) 对应的等式为 \([i \& j = j]\),也就是说:
\]
相当于子集求和!
void fwtor(int n, int inv = {1, -1}) {
for (int u = 2, k = 1; u <= n; u <<= 1, k <<= 1)
for (int i = 0; i < n; i += u)
for (int j = 0; j < k; ++j)
fwt[i + j + k] += fwt[i + j] * inv;
}
\(\texttt{and}\)
首先还是注意到 \(c(0/1, 0/1) \in \{0, 1\}\)。
考虑 \(c(0, 0) c(0, 1) = c(0, 0)\) 得出 \(c(0, 0) = 0\) 或者 \(c(0, 0) = c(0, 1) = 1\)。
同理考虑 \(c(1, 0) c(1, 1) = c(1, 0)\) 得出 \(c(1, 0) = 0\) 或者 \(c(1, 0) = c(1, 1) = 1\)。
那么还是:
1 & 1 \\ 0 & 1
\end{bmatrix} \text{或者}
\begin{bmatrix}
0 & 1 \\ 1 & 1
\end{bmatrix}
\]
值得注意的是,第一种矩阵 \(c(i, j)\) 对应的是 \([i \& j = i]\),也就是说:
\]
相当于超集求和!
void fwtand(int n, int inv = {1, -1}) {
for (int u = 2, k = 1; u <= n; u <<= 1, k <<= 1)
for (int i = 0; i < n; i += u)
for (int j = 0; j < k; ++j)
fwt[i + j] += fwt[i + j + k] * inv;
}
\(\texttt{xor}\)
考虑对于任意 \(x, y \in \{0, 1\}\) 存在 \(c(0, 0) c(x, y) = c(x, y)\),那么一定存在 \(c(0, 0) = 1\),否则 \(c(1, 1) = c(1, 0) = 0\) 显然没有逆,不可行。
考虑 \(c(0, 1) c(0, 1) = c(0, 0)\),那么 \(c(0, 1) = \pm 1\)。
\(c(1, 0) c(1, 0) = c(1, 1) c(1, 1) = c(1, 0)\),所以 \(c(1, 0) = 1\),否则 \(c(1, 1) = c(1, 0) = 0\) 则显然没有逆。
\(c(1, 1) c(1, 1) = c(1, 0)\),考虑到 \(c(1, 0) = 1\),那么自然 \(c(1, 1) = \pm 1\)。
所以可行的矩阵为:
1 & 1 \\ 1 & -1
\end{bmatrix}
\text{或者}
\begin{bmatrix}
1 & -1 \\ 1 & 1
\end{bmatrix}
\]
注意到对于第一个矩阵,实际上的系数为 \((-1)^{|i \& j|}\)。啥也不相当于。
void fwtxor(int n, int inv = {1, 1/2}) {
for (int u = 2, k = 1; u <= n; u <<= 1, k <<= 1)
for (int i = 0; i < n; i += u)
for (int j = 0; j < k; ++j) {
int x = fwt[i + j], y = fwt[i + j + k];
fwt[i + j] = (x + y) * inv, fwt[i + j + k] = (x - y) * inv;
}
}
算法学习笔记(45): 快速沃尔什变换 FWT的更多相关文章
- 算法学习笔记(17): 快速傅里叶变换(FFT)
快速傅里叶变换(FFT) 有趣啊,都已经到NOI的难度了,救命 首先,我们先讲述一下前置知识.已经明白的读者请移步后文 虚数 定义:\(z = a + bi\),其中 \(a, b \in R\ \ ...
- 一个数学不好的菜鸡的快速沃尔什变换(FWT)学习笔记
一个数学不好的菜鸡的快速沃尔什变换(FWT)学习笔记 曾经某个下午我以为我会了FWT,结果现在一丁点也想不起来了--看来"学"完新东西不经常做题不写博客,就白学了 = = 我没啥智 ...
- 【学习笔鸡】快速沃尔什变换FWT
[学习笔鸡]快速沃尔什变换FWT OR的FWT 快速解决: \[ C[i]=\sum_{j|k=i} A[j]B[k] \] FWT使得我们 \[ FWT(C)=FWT(A)*FWT(B) \] 其中 ...
- 快速沃尔什变换FWT
快速沃尔什变换\(FWT\) 是一种可以快速完成集合卷积的算法. 什么是集合卷积啊? 集合卷积就是在集合运算下的卷积.比如一般而言我们算的卷积都是\(C_i=\sum_{j+k=i}A_j*B_k\) ...
- 集合并卷积的三种求法(分治乘法,快速莫比乌斯变换(FMT),快速沃尔什变换(FWT))
也许更好的阅读体验 本文主要内容是对武汉市第二中学吕凯风同学的论文<集合幂级数的性质与应用及其快速算法>的理解 定义 集合幂级数 为了更方便的研究集合的卷积,引入集合幂级数的概念 集合幂级 ...
- Johnson算法学习笔记
\(Johnson\)算法学习笔记. 在最短路的学习中,我们曾学习了三种最短路的算法,\(Bellman-Ford\)算法及其队列优化\(SPFA\)算法,\(Dijkstra\)算法.这些算法可以快 ...
- 算法学习笔记(3): 倍增与ST算法
倍增 目录 倍增 查找 洛谷P2249 重点 变式练习 快速幂 ST表 扩展 - 运算 扩展 - 区间 变式答案 倍增,字面意思即"成倍增长" 他与二分十分类似,都是基于" ...
- Miller-Rabin 与 Pollard-Rho 算法学习笔记
前言 Miller-Rabin 算法用于判断一个数 \(p\) 是否是质数,若选定 \(w\) 个数进行判断,那么正确率约是 \(1-\frac{1}{4^w}\) ,时间复杂度为 \(O(\log ...
- 算法学习笔记(9): 中国剩余定理(CRT)以及其扩展(EXCRT)
扩展中国剩余定理 讲解扩展之前,我们先叙述一下普通的中国剩余定理 中国剩余定理 中国剩余定理通过一种非常精巧的构造求出了一个可行解 但是毕竟是构造,所以相对较复杂 \[\begin{cases} x ...
- 算法学习笔记(20): AC自动机
AC自动机 前置知识: 字典树:可以参考我的另一篇文章 算法学习笔记(15): Trie(字典树) KMP:可以参考 KMP - Ricky2007,但是不理解KMP算法并不会对这个算法的理解产生影响 ...
随机推荐
- eclipse tomcat的一些错误
eclipse tomcat运行错误 错误提示: Server Tomcat v7.0 Server at localhost was unable to start within 45 second ...
- 力扣661(java)-图片平滑器(简单)
题目: 图像平滑器 是大小为 3 x 3 的过滤器,用于对图像的每个单元格平滑处理,平滑处理后单元格的值为该单元格的平均灰度. 每个单元格的 平均灰度 定义为:该单元格自身及其周围的 8 个单元格的 ...
- 五分钟学会使用 go modules(含在家办公使用技巧)
导读:go modules 是 golang 1.11 新加的特性.如今 1.13 都已经发布了第 7 个小版本了,几乎所有大项目均已开始使用,这自然也包括 Kubernetes 生态中的众多项目.笔 ...
- Java应用结构规范
简介:在Java程序开发中,命名和应用分层无疑是广大后端同胞的两大"痛点",本文提供一种基于领域模型的轻量级应用分层结构设计,供大家参考.下面按分层结构.分层明细.调用关系.各层 ...
- 这样才是代码管理和 Commit 的正确姿势! | 研发效能提升36计
简介:效能提升从小习惯开始,这样才是代码管理和 Commit 的正确姿势! 专栏策划|雅纯 志愿编辑|张晟 软件交付是以代码为中心的交付过程,其中代码的作用有几点:第一,最终的制品要交付成什么样 ...
- [FAQ] Win10 键盘输入的数字英文字体变宽, 胖英文, 如何处理
输入法 点击右键,找到设置,点击进入. 开启 "全/半角切换" 快捷键为 "Shift + 空格",随后可以使用这个快捷键进行切换正常. Link:https: ...
- [Gin] 运行模式检测和设置 (mode.go)
// 设置方式 gin.SetMode(gin.ReleaseMode) // 检测方式 if gin.Mode() == gin.DebugMode { } 更多相关信息,建议直接去看源代码. Re ...
- ASP.NET CORE 发布时不编译Views文件夹
.net core 3.0正式版已经发布,目前整体相对来说已经稳定了,可以进行生产开发. 发布时默认情况下Views是直接编译成DLL文件(XXXXXX.Views.dll),日常开发维护过程中,经常 ...
- NopCommerce支持多种类型的数据库
本文章的内容是根据本人阅读NopCommerce源码的理解,如有不对的地方请指正,谢谢. 阅读目录 1.类结构关系图 2.分析 3.NopCommerce应用 类结构关系图 分析 NopObjectC ...
- Blazor/Hybird 触屏下单程序调优笔记
环境 Blazor Net8.0 + FreeSql + Bootstrap Blazor 组件 以下都是自己瞎琢磨的和官网资料搬运,肯定有不少错漏和不合理的地方,非常希望各位大佬评论区给我建议和意见 ...