【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$ ...
随机推荐
- ZT-----用javascrip写一个区块链
几乎每个人都听说过像比特币和以太币这样的加密货币,但是只有极少数人懂得隐藏在它们背后的技术.在这篇博客中,我将会用JavaScript来创建一个简单的区块链来演示它们的内部究竟是如何工作的.我将会称之 ...
- CSP201403-3:命令行选项
引言:CSP(http://www.cspro.org/lead/application/ccf/login.jsp)是由中国计算机学会(CCF)发起的"计算机职业资格认证"考试, ...
- Action Required: Listings Deactivated for Potential Pricing Error
Dear Seller, We are contacting you because we have detected potential pricing errors in your Amazon. ...
- hive 2以上版本启动异常 Unable to instantiate org.apache.hadoop.hive.ql.metadata.SessionHiveMetaStoreClient
hive2.0以上的版本启动时 抛出 “Unable to instantiate org.apache.hadoop.hive.ql.metadata.SessionHiveMetaStoreCli ...
- php的大小写敏感问题整理
php的大小写敏感问题整理 今天在开发php的过程中,因为命名大小写的问题导致代码错误,所以从网上整理了php的大小写敏感的一些资料,需要的朋友可以参考下. PHP对大小写敏感问题的处理比较乱,写 ...
- Leftmost Digit(数学)
Description Given a positive integer N, you should output the leftmost digit of N^N. Input The inp ...
- Scrum立会报告+燃尽图 03
此作业要求:[https://edu.cnblogs.com/campus/nenu/2018fall/homework/2190] 一.小组介绍 组长:王一可 组员:范靖旋,王硕,赵佳璐,范洪达,祁 ...
- Android 中的广播机制
Android 中的广播机制 Android 中的广播,按照广播响应范围,可以分为应用内广播和全局广播.按照广播的接收方式,可以分为标准广播和有序广播. 广播的分类 响应范围 应用内广播:此类广播只能 ...
- 关于jsp之间href传参(中文)乱码问题
在A.jsp中有href传值 <a href=\"6.jsp?param="+rs.getString(2)+"\">" 在B.jsp中使 ...
- 解决pciss_spc导入提示表空间不存在以及扩展失败的问题
select NAME FROM USER$ ORDER BY NAME ; CREATE USER pciss IDENTIFIED BY pciss ; GRANT DBA TO pciss ; ...