Fast Walsh Transform 学习笔记 | FWT
本文中使用 \(\cap\) 表示按位与,用 \(\cup\) 表示按位或
Part 1. 与/或 卷积
First. 问题引入
给定长度为 \(2^n\) 的数列 \(A,B\),求 \(C_i = \sum_{j \cup k = i} A_j \times B_k\)
显然有 \(O(4^n)\) 的暴力
Second. 变换
这一部分可以参考 快速莫比乌斯变换中的 Zeta 变换 ,即定义 \(\hat A_i\) 为序列 \(A\) 中 \(i\) 的子集和
Third. 快速变换
考虑分治
对于长度为 \(2^n\) 的待求解的 \(\hat A\),我们把它分成独立的两部分,即 \([0,2^{n-1})\) 和 \([2^{n-1},2^n)\) 两个区间分别求解
然后考虑这两个区间之间的贡献,发现只有 \([0,2^{n-1})\) 对 \([2^{n-1},2^n)\) 有贡献,于是对于 \(i \in [0,2^{n-1})\),将 \(\hat A_{i}\) 加到 \(\hat A_{i+2^{n-1}}\) 中即可
时间复杂度 \(O(n 2^n)\)
Fourth. 逆变换
我们只需要对照正变换中的操作步骤,一步一步撤销变换即可
即对于 \(i \in [0,2^{n-1})\),将 \(\hat A_{i+2^{n-1}}\) 减去 \(\hat A_{i}\) 的贡献,然后再递归地求解
当然还有另外的做法,即我们要将长度为 \(2^n\) 的 \(\hat A_i\) 在全集为 \(2^n-1\) 的情况下(即不考虑目前的长度外的子集)只包括自己的 \(A_i\),那么我们递归地求解完左右两个区间后,肯定有 \(\forall i\in [0,2^{n-1}),\hat A_{i+2^{n-1}}=\hat A_i+A_{i+2^{n-1}}\),因此减去贡献即可
in brief,可以先递归再减贡献,这样逆变换与正变换只有一个 +/- 的变化
Fifth. 推广
对于 \(\cap\) 的情况,与 \(\cup\) 十分相似,请读者尽量自己构造变换,推一下式子,可以加深理解
如果没有思路,here
Part 2. 异或 卷积
First. 问题引入
给定长度为 \(2^n\) 的数列 \(A,B\),求 \(C_i = \sum_{j \oplus k = i} A_j \times B_k\)
Second. 原理
设 \(\operatorname{popcnt}(i)\) 表示 \(i\) 在二进制下 1 的个数,则有
\]
证明:显然 \(k\) 为 \(0\) 的位上,\(i,j\) 的取值不影响结果,那么设 \(i'=i\cap k,j'=j\cap k\),那么问题转化为
\[\operatorname{popcnt}(i') + \operatorname{popcnt}(j') \equiv \operatorname{popcnt}(i'\oplus j') \pmod 2
\]对于 \(i',j'\) 每一位分开讨论,原命题易证
即异或不会改变 \(1\) 的总数的奇偶性
Third. 变换
我们尝试构造一个变换
\]
例如对于 \(\cup\) 卷积 ,\(g(i,j)=[i\cup j=i]\)
这个 \(g\) 函数满足以下性质:
& \because \hat C_i = \hat A_i \times \hat B_i \\
& \therefore \sum_{p} g(i,p)C_p = \sum_{j,k} g(i,j)\times g(i,k)\times A_j \times B_k \\
& \therefore \sum_{p} g(i,p) \sum_{j \oplus k = p} A_j \times B_k = \sum_{j,k} g(i,j)\times g(i,k)\times A_j \times B_k \\
& \therefore \sum_{j,k} g(i,j \oplus k) A_j \times B_k = \sum_{j,k} g(i,j)\times g(i,k)\times A_j \times B_k
\end{align}
\]
即我们要使得 \(g(i,j)\times g(i,k) = g(i,j \oplus k)\)
因为 \(\operatorname{popcnt}(i \cap k) + \operatorname{popcnt}(j \cap k) \equiv \operatorname{popcnt}((i\oplus j)\cap k) \pmod 2\),我们发现 \(g(i,j) = (-1)^{\operatorname{popcnt}(i \cap j)}\) 满足这个性质
\]
手动推一下式子:
\hat A_i \times \hat B_i & = \sum_j g(i,j)A_j \times \sum_k g(i,k) B_k\\
& = \sum_j (-1)^{\operatorname{popcnt}(i \cap j)} A_j \times \sum_k (-1)^{\operatorname{popcnt}(i \cap k)} B_k\\
& = \sum_{j,k} (-1)^{\operatorname{popcnt}(i \cap j) + \operatorname{popcnt}(i \cap k)} A_j \times B_k \\
& = \sum_{j,k} (-1)^{\operatorname{popcnt}(i \cap (j \oplus k))} C_{j \oplus k} \\
& = \sum_{p} (-1)^{\operatorname{popcnt}(i \cap p)} C_p \\
& = \sum_p g(i,p) C_p \\
& = \hat C_i
\end{align}
\]
Fourth. 快速变换
有点抽象,画个 \(n=3\) 的图来模拟一下
假设现在我们要考虑从 \(n=2\) 到 \(n=3\) 的变换,我们发现左边是 0??,右边是 1??,分别多出一个最高位
设原变换为 \(F_i\) ,目标变换为 \(G_i\)
左 \(\to\) 左
我们发现左边内部之间的 \(\cup\) 结果不变,因此 \(\forall i<4, G_i \gets F_i\)
左 \(\to\) 右 / 右 \(\to\) 左
我们发现
0??\(\cup\)1??=0??,因此其1的个数不变,因此 \(\forall i<4,G_i \gets F_{i+4}, G_{i+4} \gets F_i\)。右 \(\to\) 右
我们发现之前是
??\(\cup\)??=??,但是现在在前面加了一个1,因此 \(-1\) 的指数加一,所以 \(\forall i<4,G_{i+4} \gets -F_{i+4}\)
综上,我们有 \(\forall i<4,G_i=F_i+F_{i+4}, G_{i+4}=F_i-F_{i+4}\)
generally,对于从 \(n-1\) 到 \(n\) 的变换,我们有
\]
时间复杂度 \(O(n2^n)\)。
Fifth. 逆变换
对照上面式子易得(留给读者思考)
Part 3. 模板题
核心代码如下
void fwtOr(ll *a,int n,int type) {
for(int i=1; i<(1<<n); i<<=1)
for(int j=0; j<(1<<n); j+=(i<<1))
for(int k=0; k<i; ++k)
(a[j+k+i]+=type*a[j+k])%=P;
}
void fwtAnd(ll *a,int n,int type) {
for(int i=1; i<(1<<n); i<<=1)
for(int j=0; j<(1<<n); j+=(i<<1))
for(int k=0; k<i; ++k)
(a[j+k]+=type*a[j+k+i])%=P;
}
void fwtXor(ll *a,int n,int type) {
for(int i=1; i<(1<<n); i<<=1)
for(int j=0; j<(1<<n); j+=(i<<1))
for(int k=0; k<i; ++k) {
ll u=a[j+k],v=a[j+k+i];
a[j+k]=(u+v)%P;
a[j+k+i]=(u-v)%P;
if(type==-1) {
(a[j+k]*=Pi2)%=P;
(a[j+k+i]*=Pi2)%=P;
}
}
}
Fast Walsh Transform 学习笔记 | FWT的更多相关文章
- [学习笔记]FWT——快速沃尔什变换
解决涉及子集配凑的卷积问题 一.介绍 1.基本用法 FWT快速沃尔什变换学习笔记 就是解决一类问题: $f[k]=\sum_{i\oplus j=k}a[i]*b[j]$ 基本思想和FFT类似. 首先 ...
- [学习笔记] $FWT$
\(FWT\)--快速沃尔什变化学习笔记 知识点 \(FWT\)就是求两个多项式的位运算卷积.类比\(FFT\),\(FFT\)大多数求的卷积形式为\(c_n=\sum\limits_{i+j=n}a ...
- ios 控件代码transform学习笔记
1.图片设置(平移,缩放,旋转) 创建一个transform属性 //按钮点击时,只能执行一次向上旋转 //派 M_PI_4 45度旋转 . CGAffineTransform transforms= ...
- css笔记 - transform学习笔记(二)
transform转换 CSS transform 属于2D/3D上的转换.变形效果.他不是一个动画,他就是变形.比如正方形变平行四边形,再变圆形.都是形状变成另一个形状. 但是如果配合上transi ...
- 「学习笔记」Fast Fourier Transform
前言 快速傅里叶变换(\(\text{Fast Fourier Transform,FFT}\) )是一种能在\(O(n \log n)\)的时间内完成多项式乘法的算法,在\(OI\)中的应用很多,是 ...
- 一个数学不好的菜鸡的快速沃尔什变换(FWT)学习笔记
一个数学不好的菜鸡的快速沃尔什变换(FWT)学习笔记 曾经某个下午我以为我会了FWT,结果现在一丁点也想不起来了--看来"学"完新东西不经常做题不写博客,就白学了 = = 我没啥智 ...
- FWT快速沃尔什变换学习笔记
FWT快速沃尔什变换学习笔记 1.FWT用来干啥啊 回忆一下多项式的卷积\(C_k=\sum_{i+j=k}A_i*B_j\) 我们可以用\(FFT\)来做. 甚至在一些特殊情况下,我们\(C_k=\ ...
- [学习笔记&教程] 信号, 集合, 多项式, 以及各种卷积性变换 (FFT,NTT,FWT,FMT)
目录 信号, 集合, 多项式, 以及卷积性变换 卷积 卷积性变换 傅里叶变换与信号 引入: 信号分析 变换的基础: 复数 傅里叶变换 离散傅里叶变换 FFT 与多项式 \(n\) 次单位复根 消去引理 ...
- FWT学习笔记
FWT学习笔记 引入 一般的多项式乘法是这样子的: \(c_i=\sum_{i,j}a_j*b_k*[j+k==i]\) 但是如果我们将这个乘法式子里面的+号变换一下变成其他的运算符号呢? \(c_i ...
- FWT 学习笔记
FWT学习笔记 好久以前写的,先粘上来 定义数组 \(n=2^k\) \(A=[a_0,a_1,a_2,a_3,...,a_{n-1}]\) 令\(A_0=[a_0,a_1,a_2,...,a_{\f ...
随机推荐
- quartus之LPM_COMPARE测试
quartus之LPM_COMPARE测试 1.IP描述 比较器的IP,可以比较两路数据是否相等.相等输出为1,不等输出为0的aeb信号是需要测试的量. 2.基础测试 module compare_t ...
- java实战字符串2:中英字符串相互转换
题目描述 输入字符串为中文拼音号码串或者英文号码串,如果输入是中文拼音号码串则转成英文号码串,如果输入是英文号码串则转成中文号码串. 特殊情况是英文号码串会出现Double + 英文数字或者拼音数值. ...
- OpenHarmony 社区运营报告(2023 年 10 月)
● 截至2023年10月,OpenHarmony社区共有51家共建单位,累计超过6200名贡献者产生24.2万多个PR,2.3万多个Star,6.1万多个Fork,59个SIG. ● OpenHa ...
- 本周二晚19:00战码先锋第5期直播丨深入理解OpenHarmony系统启动,轻松踏上设备软件开发之旅
OpenAtom OpenHarmony(以下简称"OpenHarmony")工作委员会首度发起「OpenHarmony开源贡献者计划」,旨在鼓励开发者参与OpenHarmony开 ...
- 运动App如何实现端侧后台保活,让运动记录更完整?
你在锻炼健身时,有没有遇到这样的情况?辛辛苦苦锻炼了几小时,却发现App停止了运行,本次运动并没有被记录到App上,从而失去了一个查看完整运动数据的机会? 运动类App是通过手机或者穿戴设备的传感器, ...
- sql注入--基础注入判断方法(构造闭合)
在我们拿到一个sql注入的题目之后,在确定了注入点之后,接下来要做的事情就是进行基础注入判断. 在开始前,我们需要理解一个SQL注入中最常用的词汇 -- 构造闭合 . 对于SQL处理语句后台的写法: ...
- 在HarmonyOS上使用ArkUI实现计步器应用
介绍 本篇Codelab使用ArkTS语言实现计步器应用,应用主要包括计步传感器.定位服务和后台任务功能: 1. 通过订阅计步器传感器获取计步器数据,处理后显示. 2. 通过订阅位置服务获取位 ...
- CentOS下修改 MySQL 的密码
做服务器运维,修改 MySQL 的密码是经常的需要,定期修改 MySQL 密码是网站安全的一个保证.这里记录一下修改 MySQL 密码的一些命令,方便以后查看. 修改root密码 CentOS 下 M ...
- 重新点亮linux 命令树————网络管理[十一二]
前言 简单整理一下网络管理. 正文 网络管理需要掌握: 网络状态查看 网络配置 路由命令 网络故障排除 网络服务管理 常用网络配置文件 网络状态的查看: 1.net-tools ---->1.i ...
- 重新整理 .net core 实践篇————防跨站脚本攻击[四十]
前言 简单整理一下跨站脚本攻击. 正文 攻击原理是这样子的: 这种攻击被攻击的面挺多的,比如说只要有一个可以让用户输入的注入脚本就都是一个问题. 给网站注入脚本 然后用户访问给网站注入的脚本 脚本里面 ...