FWT快速沃尔什变换——基于朴素数学原理的卷积算法
这是我的第一篇学习笔记,如有差错,请海涵...
目录
引子
首先,考虑这是兔子

数一数,会发现你有一只兔子,现在,我再给你一只兔子


再数一数,会发现什么?没错,你有两只兔子,也就是说,1+1=2!
这就是算数的基本原理了,聪明的你懂了吗?
好,我们可以学FWT了..
卷积形式
我们回忆一下多项式乘法的式子:
这个可以用FFT或NTT优化到O(nlogn)求出每一个Ci,但不是本章的重点,只是引出卷积的概念:
而FWT主要是解决以下三种卷积形式:
算法流程
卷积的算法原理就是把一个数列快速转换成另一种数列,然后每一位元素之间就可以直接单独相乘计算,最后再把答案数列快速转换回来。
FFT体现这个原理的方式就是把多项式转换成点值表达式,然后由于每个点的横坐标相同,纵坐标直接乘起来就得到最终的点值表达式,最后把答案的多项式表达通过点值表达式解出来。
那FWT怎么做呢?
首先就是数列长度的问题,我们知道,多项式乘法最终会得到一个长为lenA+lenB-1的多项式,而考虑位运算的卷积——很容易想出,最终的数列长度一定是,n是A、B大小转换为二进制后的数的最大位数。
我们设数列A的转换数列是DWT(A),转换后的数列A的原数列是IDWT(A)
既然它是位运算,那么我们就按位分治
我们从二进制最高位考虑起,每次把当前位为0或1的元素分开成两个数列,很显然,由于数列长度为,直接每次从中间分开就好了,
那么
这里的“{ , }”是把两个数列前后拼一起,A+B是把两个数列排头对齐,然后每一位相加。
具体的系数a,b,c,d是怎么样,or , and 和 xor 的情况是不一样的。
OR卷积
因为是按位或,所以当前位为1的对0没有影响,而0的元素都要对1有影响(0可以 | 1变成1,但是1怎么 | 都不会变成0),于是它的DWT就是这样
这样DWT(A)[i]就相当于下标按位或 i 后等于 i 的元素和,转换回去刚好就把当前位为1的减去为0的就行,即
这就是DWT的逆运算形式吧。
ps:巧合的是,这个玩意其实也是快速莫比乌斯变换FMT,两个是一样的,完全没有区别,也就是说DWT(A)[i]其实也是i的所有子集元素和。
举个栗子
,
解决了!
AND卷积
和or很相像
因为是按位与,所以当前位为0的对1没有影响,而1的元素都要对0有影响(1可以&0变成0,但是0怎么&都不会变成1),于是它的DWT就是这样
这样DWT(A)[i]就相当于下标按位与 i 后等于 i 的元素和,转换回去刚好就把当前位为0的减去为1的就行,即
这又刚好是DWT的逆运算了。
再举个栗子
,
XOR卷积
这个就比较特殊了
我们从栗子里会发现,对于异或,我们最后其实要把 a0b0+a1b1 和 a1b0+a0b1 单独刨出来。(这不是废话!)
那么在DWT(C)中,a0b0的系数要和a1b1一样,a1b0的系数要和a0b1一样
……
于是它的DWT就是这样!:
这样DWT(C)就符合条件了,它的IDWT是
这个得看栗子才明白
,
模板
下面是非递归版本的DWT以及IDWT,m为数列长度()
inline void DWTOR(int *s,int m) {
for(int k = m;k > 1;k >>= 1) {
for(int i = 0;i < m;i += k) {
for(int j = i+(k>>1);j < i+k;j ++) {
int s0 = s[j-(k>>1)],s1 = s[j];
s[j] = qm((s0 +0ll+ s1) , zxy);
}
}
}
return ;
}
inline void IDWTOR(int *s,int m) {
for(int k = 2;k <= m;k <<= 1) {
for(int i = 0;i < m;i += k) {
for(int j = i+(k>>1);j < i+k;j ++) {
int s0 = s[j-(k>>1)],s1 = s[j];
s[j] = qm((s1 +0ll+ zxy - s0) , zxy);
}
}
}
return ;
}
inline void DWTAND(int *s,int m) {
for(int k = m;k > 1;k >>= 1) {
for(int i = 0;i < m;i += k) {
for(int j = i+(k>>1);j < i+k;j ++) {
LL s0 = s[j-(k>>1)],s1 = s[j];
s[j-(k>>1)] = qm((s0 +0ll+ s1) , zxy);
}
}
}
return ;
}
inline void IDWTAND(int *s,int m) {
for(int k = 2;k <= m;k <<= 1) {
for(int i = 0;i < m;i += k) {
for(int j = i+(k>>1);j < i+k;j ++) {
int s0 = s[j-(k>>1)],s1 = s[j];
s[j-(k>>1)] = qm((s0 +0ll+ zxy - s1) , zxy);
}
}
}
return ;
}
inline void DWTXOR(int *s,int m) {
for(int k = m;k > 1;k >>= 1) {
for(int i = 0;i < m;i += k) {
for(int j = i+(k>>1);j < i+k;j ++) {
int s0 = s[j-(k>>1)],s1 = s[j];
s[j] = qm((s0 +0ll+ zxy - s1) , zxy);
s[j-(k>>1)] = qm((s0 +0ll+ s1) , zxy);
}
}
}
return ;
}
inline void IDWTXOR(int *s,int m) {
for(int k = 2;k <= m;k <<= 1) {
for(int i = 0;i < m;i += k) {
for(int j = i+(k>>1);j < i+k;j ++) {
int s0 = s[j-(k>>1)],s1 = s[j];
s[j-(k>>1)] = qm((s0 +0ll+ s1) , zxy) *1ll* inv2 % zxy;
s[j] = qm((s0 +0ll+ zxy - s1) , zxy) *1ll* inv2 % zxy;
}
}
}
return ;
}
FWT就到这里了,大家都懂了吧
FWT快速沃尔什变换——基于朴素数学原理的卷积算法的更多相关文章
- FWT快速沃尔什变换学习笔记
FWT快速沃尔什变换学习笔记 1.FWT用来干啥啊 回忆一下多项式的卷积\(C_k=\sum_{i+j=k}A_i*B_j\) 我们可以用\(FFT\)来做. 甚至在一些特殊情况下,我们\(C_k=\ ...
- [学习笔记]FWT——快速沃尔什变换
解决涉及子集配凑的卷积问题 一.介绍 1.基本用法 FWT快速沃尔什变换学习笔记 就是解决一类问题: $f[k]=\sum_{i\oplus j=k}a[i]*b[j]$ 基本思想和FFT类似. 首先 ...
- 浅谈算法——FWT(快速沃尔什变换)
其实FWT我啥都不会,反正就是记一波结论,记住就好-- 具体证明的话,推荐博客:FWT快速沃尔什变换学习笔记 现有一些卷积,形如 \(C_k=\sum\limits_{i\lor j=k}A_i*B_ ...
- 知识点简单总结——FWT(快速沃尔什变换),FST(快速子集变换)
知识点简单总结--FWT(快速沃尔什变换),FST(快速子集变换) 闲话 博客园的markdown也太傻逼了吧. 快速沃尔什变换 位运算卷积 形如 $ f[ i ] = \sum\limits_{ j ...
- 初学FWT(快速沃尔什变换) 一点心得
FWT能解决什么 有的时候我们会遇到要求一类卷积,如下: Ci=∑j⊕k=iAj∗Bk\large C_i=\sum_{j⊕k=i}A_j*B_kCi=j⊕k=i∑Aj∗Bk此处乘号为普通乘法 ...
- FWT快速沃尔什变换例题
模板题 传送门 #include<bits/stdc++.h> #define ll long long #define max(a,b) ((a)>(b)?(a):(b)) #de ...
- FWT快速沃尔什变换
前言 学多项式怎么能错过\(FWT\)呢,然而这真是个毒瘤的东西,蒟蒻就只会背公式了\(\%>\_<\%\) 或卷积 \[\begin{aligned}\\ tf(A) = (tf(A_0 ...
- BP神经网络的数学原理及其算法实现
什么是BP网络 BP网络的数学原理 BP网络算法实现 转载请声明出处http://blog.csdn.net/zhongkejingwang/article/details/44514073 上一篇 ...
- 一个数学不好的菜鸡的快速沃尔什变换(FWT)学习笔记
一个数学不好的菜鸡的快速沃尔什变换(FWT)学习笔记 曾经某个下午我以为我会了FWT,结果现在一丁点也想不起来了--看来"学"完新东西不经常做题不写博客,就白学了 = = 我没啥智 ...
随机推荐
- 3. Docker应用
- UiPath官方视频Level1
[UiPath官方视频Level1]第一课-UiPath简介https://www.bilibili.com/video/BV1zJ41187vB [UiPath官方视频Level1]第二课-变量和数 ...
- 【摸鱼神器】UI库秒变低代码工具——表单篇(一)设计
前面说了列表的低代码化的方法,本篇介绍一下表单的低代码化. 内容摘要 需求分析. 定义 interface. 定义表单控件的 props. 定义 json 文件. 基于 el-form 封装,实现依赖 ...
- 深入浅出理解SVM支持向量机算法
支持向量机是Vapnik等人于1995年首先提出的,它是基于VC维理论和结构风险最小化原则的学习机器.它在解决小样本.非线性和高维模式识别问题中表现出许多特有的优势,并在一定程度上克服了" ...
- 强化学习-学习笔记8 | Q-learning
上一篇笔记认识了Sarsa,可以用来训练动作价值函数\(Q_\pi\):本篇来学习Q-Learning,这是另一种 TD 算法,用来学习 最优动作价值函数 Q-star,这就是之前价值学习中用来训练 ...
- 论文解读(ValidUtil)《Rethinking the Setting of Semi-supervised Learning on Graphs》
论文信息 论文标题:Rethinking the Setting of Semi-supervised Learning on Graphs论文作者:Ziang Li, Ming Ding, Weik ...
- Root用户无法使用Tab补齐解决
1. sudo vim /etc/bash.bashrc 2.取消以下注释 #if [ -f /etc/bash_completion ]; then # . /etc/bash_completion ...
- k8s+crio+podman搭建集群
前言 在传统的k8s集群中,我们都是使用docker engine做为底层的容器管理软件的,而docker engine因为不是k8s亲生的解决方案,所以实际使用中会有更多的分层.之前我们也讲过,k8 ...
- IDEA快捷键之html篇-1
前端IDE中Emmet插件快捷输入HTML代码 前端IDE如VSCode.Atom.Sublime Text和Intellij Idea中使用Emmet插件快捷输入HTML代码的介绍 前端IDE中 ...
- Webpack干货系列 | Webpack5 怎么处理字体图标、图片资源
程序员优雅哥(youyacoder)简介:十年程序员,呆过央企外企私企,做过前端后端架构.分享vue.Java等前后端技术和架构. 本文摘要:主要讲解在不需要引入额外的loader的条件下运用Webp ...