【learning】快速沃尔什变换FWT
## 问题描述
已知\(A(x)\)和\(B(x)\),\(C[i]=\sum\limits_{j\otimes k=i}A[j]*B[k]\),求\(C\)
其中\(\otimes\)是三种位运算的其中一种
具体求解
说在前面:接下来的一些符号的话我们统一用\(\otimes\)代表某种位运算(选定的),如果这个符号出现在两个多项式之间(如:\(A\otimes B\)),那么是表示按照最上面那条式子卷积,如果出现在两个数之间(如\(j\otimes k\)),那么是表示这两个数进行这种位运算;然后我们用$\ \cdot$这个符号表示点积(也就是对应数位相乘)
这里我们用与运算(\(\otimes=\&\))举例说明好了,另外两个差不多的
首先来个不太靠谱的联想,这个东西的名字长得跟FFT那么像那是不是可以借用FFT的形式啊(Portal -->FFT)
然后我们考虑构造一种变换\(F(A)\)(额其实就是FWT),其中\(A\)是一个多项式,这个变换满足:
&F(A)\cdot F(B)=F(A\otimes B)\\
&F(k* A)=k*F(A)\\
&F(A+B)=F(A)+F(B)\\
\end{aligned}
\]
这样我们就可以像FFT一样,先用某种方法求出\(F(A)\)和\(F(B)\)然后对应位相乘,再把得到的结果逆变换一下就可以得到\(C(x)\)了
那么现在的问题是我们怎么构造\(F\)
参考FFT的求解我们还是尝试用分治的思想来解决这个问题
与FFT按照下标的奇偶性分类不同,因为位运算是跟二进制有关的,所以我们可以考虑按照下标的二进制最高位为\(0\)还是为\(1\)分成两类(因为算的时候长度是补成\(2^k\)这样的,所以其实也就是严格的前半部分和后半部分)
对于一个多项式\(A\),下标二进制最高位为\(0\)的那部分记为\(A_0\),为\(1\)的那部分记为\(A_1\),\(A=(A_0,A_1)\)
我们可以猜测一下这个\(F(A)=(k_1A_0+k_2A_1,k_3A_0+k_4A_1)\)
其中\(k_1,k_2,k_3,k_4\)都是常数
然后现在我们要做的就是求出这四个常数
我们将\(A\otimes B\)写成\((A_0,A_1)\otimes (B_0,B_1)\),然后看一下这个式子等于什么:
同样的我们还是将结果写成\((C_0,C_1)\)的形式,那么根据与运算的特点我们可以的到:
(A_0,A_1)\otimes (B_0,B_1)=(A_0\otimes B_0+A_0\otimes B_1+A_1\otimes B_0,A_1\otimes B_1)\\
\end{aligned}
\]
(具体一点的话就是\(0\&0=0,0\&1=0,1\&0=0\)所以都是\(C_0\)的组成部分,只有\(1\&1=1\)是\(C_1\)的组成部分)
然后我们根据最上面的\(F\)这个变换满足的性质和我们猜测的\(F(A)=(k_1A_0+k_2A_1,k_3A_0+k_4A_1)\)来处理一下这个式子
(因为\(k_1,k_2\)和\(k_3,k_4\)满足的条件其实是一样的所以在下面化的时候我们可以只考虑前半部分的求解(也就是就解\(k_1,k_2\),所有的变换什么的只写前半部分),然后求得多组解最后取其中两个可行解分别作为\(k_1,k_2,k_3,k_4\)即可)
(因为太长了。。所以一个等式我就换行来写了qwq)
&(k_1A_0+k_2A_1)\cdot (k_1B_0+k_2B_1)\\
=&k_1(A_0\otimes B_0+A_0\otimes B_1+A_1\otimes B_0)+ k_2(A_1\otimes B_1)\\
\\
&\Updownarrow\\
\\
&k_1^2(A_0\otimes B_0)+k_1k_2(A_0\otimes B_1)+k_1k_2(A_1\otimes B_0)+k_2^2(A_1\otimes B_1)\\
=&k_1(A_0\otimes B_0)+k_1(A_0\otimes B_1)+k_1(A_1\otimes B_0)+k_2(A_1\otimes B_1)
\end{aligned}
\]
然后我们就可以直接得到一个比较好看的方程组了:
k_1^2=k_1\\
k_1k_2=k_1\\
k_2^2=k_2\\
\end{cases}
\]
然后我们解出来有三组解:\((0,0),(1,1),(0,1)\)
接下来要做的就是从这三组解里面挑两组出来作为\((k_1,k_2)\)和\((k_3,k_4)\)
但这个并不是随便挑的,考虑到我们的这个变换必须要有一个逆变换,所以我们挑出来的两组不能是有一组是\((0,0)\)或者有两组相等(不然就不可逆了嘛),实际上,我们可以将这四个系数写成一个矩阵,然后逆变换的系数的话就是对这个矩阵求个逆就好了
所以,这里我们只能选\((1,1)\)和\((0,1)\),我们令\((k_1,k_2)=(1,1)\),\((k_3,k_4)=(0,1)\)
k_1&k_2\\
k_3&k_4\\
\end{bmatrix}=
\begin{bmatrix}
1&1\\
0&1\\
\end{bmatrix}
\]
然后我们把这个东西求一下逆,得到逆矩阵:
1&-1\\
0&1\\
\end{bmatrix}
\]
(具体求解的话。。当然可以直接用线代的那套但是qwq这里那么小那直接设数代一下就好了,设四个数然后矩乘一下等于单位矩阵)
然后我们按照这个系数去算FWT(也就是变换\(F\))和逆FWT就好啦
然后如果是求异或或者是或运算的话,那直接改一下
\]
这个式子的左边然后再用同样的方法算一下就好了
xor的话就是:\((A_0\otimes B_0+A_1\otimes B_1,A_0\otimes B_1+A_1\otimes B_0)\)
or的话就是:\((A_0\otimes B_0,A_0\otimes B_1+A_1\otimes B_0+A_1\otimes B_1)\)
代码什么的长得跟FFT其实差不多。。。哦不对。。会短很多ovo
大概是长这个样子:
#define OR 0
#define AND 1
#define XOR 2
void fwt(int *a,int op,int type,int len){//op=1为FWT,否则为逆FWT
int v,u;
for (int step=2;step<=len;step<<=1)
for (int st=0;st<len;st+=step)
for (int i=0;i<step>>1;++i){
u=a[st+i]; v=a[st+i+(step>>1)];//u=A0,v=A1
if (op==1){
if (type==XOR)
a[st+i]=(u+v)%MOD,a[st+i+(step>>1)]=(u+MOD-v)%MOD;
else if (type==AND)
a[st+i]=(u+v)%MOD;
else
a[st+i+(step>>1)]=(u+v)%MOD;
}
else{
if (type==XOR)
a[st+i]=1LL*(u+v)*inv2%MOD,a[st+i+(step>>1)]=1LL*(1LL*u+MOD-v)*inv2%MOD;
else if (type==AND)
a[st+i]=(1LL*u-v+MOD)%MOD;
else
a[st+i+(step>>1)]=(1LL*v-u+MOD)%MOD;//v-u!!
}
}
}
【learning】快速沃尔什变换FWT的更多相关文章
- 一个数学不好的菜鸡的快速沃尔什变换(FWT)学习笔记
一个数学不好的菜鸡的快速沃尔什变换(FWT)学习笔记 曾经某个下午我以为我会了FWT,结果现在一丁点也想不起来了--看来"学"完新东西不经常做题不写博客,就白学了 = = 我没啥智 ...
- 快速沃尔什变换FWT
快速沃尔什变换\(FWT\) 是一种可以快速完成集合卷积的算法. 什么是集合卷积啊? 集合卷积就是在集合运算下的卷积.比如一般而言我们算的卷积都是\(C_i=\sum_{j+k=i}A_j*B_k\) ...
- 集合并卷积的三种求法(分治乘法,快速莫比乌斯变换(FMT),快速沃尔什变换(FWT))
也许更好的阅读体验 本文主要内容是对武汉市第二中学吕凯风同学的论文<集合幂级数的性质与应用及其快速算法>的理解 定义 集合幂级数 为了更方便的研究集合的卷积,引入集合幂级数的概念 集合幂级 ...
- 【学习笔鸡】快速沃尔什变换FWT
[学习笔鸡]快速沃尔什变换FWT OR的FWT 快速解决: \[ C[i]=\sum_{j|k=i} A[j]B[k] \] FWT使得我们 \[ FWT(C)=FWT(A)*FWT(B) \] 其中 ...
- 关于快速沃尔什变换(FWT)的一点学习和思考
最近在学FWT,抽点时间出来把这个算法总结一下. 快速沃尔什变换(Fast Walsh-Hadamard Transform),简称FWT.是快速完成集合卷积运算的一种算法. 主要功能是求:,其中为集 ...
- 快速沃尔什变换 FWT 学习笔记【多项式】
〇.前言 之前看到异或就担心是 FWT,然后才开始想别的. 这次学了 FWT 以后,以后判断应该就很快了吧? 参考资料 FWT 详解 知识点 by neither_nor 集训队论文 2015 集合幂 ...
- Codeforces 662C(快速沃尔什变换 FWT)
感觉快速沃尔什变换和快速傅里叶变换有很大的区别啊orz 不是很明白为什么位运算也可以叫做卷积(或许不应该叫卷积吧) 我是看 http://blog.csdn.net/liangzhaoyang1/ar ...
- HDU 5977 Garden of Eden (树形dp+快速沃尔什变换FWT)
CGZ大佬提醒我,我要是再不更博客可就连一月一更的频率也没有了... emmm,正好做了一道有点意思的题,就拿出来充数吧=.= 题意 一棵树,有 $ n (n\leq50000) $ 个节点,每个点都 ...
- BZOJ4589 Hard Nim(快速沃尔什变换FWT)
这是我第一道独立做出来的FWT的题目,所以写篇随笔纪念一下. (这还要纪念,我太弱了) 题目链接: BZOJ 题目大意:两人玩nim游戏(多堆石子,每次可以从其中一堆取任意多个,不能操作就输).$T$ ...
随机推荐
- 1.0 Hadoop的介绍、搭建、环境
HADOOP背景介绍 1.1 Hadoop产生背景 HADOOP最早起源于Nutch.Nutch的设计目标是构建一个大型的全网搜索引擎,包括网页抓取.索引.查询等功能,但随着抓取网页数量的增加,遇到了 ...
- 131. 分割回文串 javascript实现
给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串. 返回 s 所有可能的分割方案. 示例: 输入: "aab" 输出: [ ["aa",&quo ...
- 技本功丨请带上纸笔刷着看:解读MySQL执行计划的type列和extra列
本萌最近被一则新闻深受鼓舞,西工大硬核“女学神”白雨桐,获6所世界顶级大学博士录取 货真价值的才貌双全,别人家的孩子 高考失利与心仪的专业失之交臂,选择了软件工程这门自己完全不懂的专业.即便全部归零, ...
- [朴孝敏][Gold]
歌词来源:http://music.163.com/#/song?id=406924220 作曲 : Ryan S. Jhun/David Quinones/Edwin Menjivar/Mateo ...
- Java:重写equals()和hashCode()
Java:重写equals()和hashCode() 1.何时需要重写equals() 当一个类有自己特有的“逻辑相等”概念(不同于对象身份的概念). 2.设计equals() [1]使用instan ...
- scrum立会报告+燃尽图(第三周第七次)
此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2286 项目地址:https://coding.net/u/wuyy694 ...
- 基于NABCD评论探路者团队贪吃蛇作品及改进建议
1.根据(不限于)NABCD评论作品的选题 N:随着人们生活压力越来越大,需要去去缓解压力,并且也需要不断进步,学习英语知识. A:它是基于java开发的一款软件,采用逐个吃字母,加长蛇身,增强记忆的 ...
- 1.2Linux下C语言开发基础(学习过程)
===============第二节 Linux下C语言开发基础=========== ********************** 重要知识点总结梳理********************* 一 ...
- 简评搜狗输入法(ios端)
首先说说为什么不使用iPhone自带的输入法呢,首先是词库不够丰富,好多简单的词语需要逐个字逐个字的选择,记忆功能不太好,其次是全键盘式的输入我不太习惯,还是九宫格的输入法比较简单,更方便快捷. 搜狗 ...
- ASP.NET 文档
标题:ASP.NET 文档 地址:https://docs.microsoft.com/zh-cn/aspnet/index#pivot=core&panel=core_overview 标题 ...