Fast Walsh-Hadamard Transform

.pre

今天本来想看FFT的应用的...翻翻picks的博客发现了好东西Fast Walsh-Hadamard Transform,感觉挺有趣的...就写了一下...orz

.intro

Fast Walsh-Hadamard Transform(FWT)是用来解决一类卷积问题的.((当整篇文章看完后)如果你还是不知道什么样的卷积能做,戳这里,最后一篇vfk大大的论文集合幂级数与xxxxxx)

准确地说,我们给出两个长度都为\(2^m\)的序列\(A_0\dots A_{2^m-1}\),\(B_0\dots B_{2^m-1}\),显然对于每一个下标我们都可以把它分解成一个唯一的长度为\(m\)的二进制数(开头补0).我们需要求出一个它们的xor卷积,即一个序列\(C_0..C_{2^m-1}\)满足:

\[C_k=\sum_{i\otimes j=k}A_iB_j
\]

其中\(a\otimes b\)表示\(a\) xor \(b\).

FWT的基本思想就是对每一位分开讨论,恩,因为xor是按位做的,我们显然可以按位讨论..

然后Picks不知道怎么做了,恩.

然而窝也不知道怎么做了,恩.

然后Picks有结论!背结论大法吼:

(等等窝先出个表示法)

由于是一个长度为\(2^m\)的序列,我们可以将此序列按数字大小二分,两半在原序列里是连续的且长度相同.显然此时我们把这个序列按照最高位分开了.我们记这个过程为\(A=(A_0,A_1)\),\(A_0\)就是小的那一半.

我们定义对于一个序列做FWT为\(tf(A)\),然后\(tf(|A|=1,A)=A_0\).\(|A|\)表示\(A\)的长度.

(结论)

这时\(tf(A)=(tf(A_0)+tf(A_1),tf(A_0)-tf(A_1))\).(错了去找Picks> <还有vfk证明过这个东西去找vfk> <)

然后...好像就没了?

当然FWT只是对一个序列A进行的操作...其实这相当于一个FFT,要求出卷积还需要再对B最一次tf(b),把结果在同一个位置上的数相乘,然后再做IFFT(口胡,其实是IFWT).

IFWT也很简单,\(itf(A)=(itf\left(\frac{A_0+A_1}{2}\right),itf\left(\frac{A_0-A_1}{2}\right))\).

(补充一个表示法)

对于两个等长的序列,我们定义

\[A+B=C \rightarrow C_k=A_k+B_k
\]

\[A-B=C \rightarrow C_k=A_k-B_k
\]

\[A\times B=C \rightarrow C_k=A_k\times B_k
\]

(总结)

那么我们就会做FWT了,因为

\[A*B=itf(tf(A)\times tf(B))
\]

.code

void fwt_xor(ll* x,int r){
for(int i=2,p=1;i<=r;i<<=1,p<<=1){
int u=r-i;
for(int j=0,ux=p;j<=u;j+=i,ux+=i){
for(int k=j;k<ux;++k){
ll kx=x[k],ky=x[k+p];
x[k]=kx+ky,x[k+p]=kx-ky;
}
}
}
}
void fwt_xor_inv(ll* x,int r){
for(int i=r,p=r>>1;p;i>>=1,p>>=1){
int u=r-i;
for(int j=0,ux=p;j<=u;j+=i,ux+=i){
for(int k=j;k<ux;++k){
x[k]=(x[k]+x[k+p])>>1;
x[k+p]=x[k]-x[k+p];
}
}
}
}

代码未经测试,慎用.

.ext

.op.and

\[tf(A)=(tf(A_0)+tf(A_1),tf(A_1))
\]

\[itf(A)=(itf(A_0)-itf(A_1),itf(A_1))
\]

void fwt_and(ll* x,int r){
for(int i=2,p=1;i<=r;i<<=1,p<<=1){
int u=r-i;
for(int j=0,ux=p;j<=u;j+=i,ux+=i){
for(int k=j;k<ux;++k) x[k]+=x[k+p];
}
}
}
void fwt_and_inv(ll* x,int r){
for(int i=2,p=1;i<=r;i<<=1,p<<=1){
int u=r-i;
for(int j=0,ux=p;j<=u;j+=i,ux+=i){
for(int k=j;k<ux;++k) x[k]-=x[k+p];
}
}
}

.op.or

\[tf(A)=(tf(A_0),tf(A_1)+tf(A_0))
\]

\[itf(A)=(itf(A_0),itf(A_1)-itf(A_0))
\]

void fwt_or(ll* x,int r){
for(int i=2,p=1;i<=r;i<<=1,p<<=1){
int u=r-i;
for(int j=0,ux=p;j<=u;j+=i,ux+=i){
for(int k=j;k<ux;++k) x[k+p]+=x[k];
}
}
}
void fwt_or_inv(ll* x,int r){
for(int i=2,p=1;i<=r;i<<=1,p<<=1){
int u=r-i;
for(int j=0,ux=p;j<=u;j+=i,ux+=i){
for(int k=j;k<ux;++k) x[k+p]-=x[k];
}
}
}

.ps

关于FWT modulo prime

我们可以显然地处理FWT modulo prime,只需要取个模就好了(不是废话么= =)..

还有...关于如何求\(2^{-1}\equiv x\pmod{p}\)中的\(x\)...直接x=(p+1)>>2...显然满足性质..

FWT for xor 的模数需要与2互素.

.pps

我可能会出一道裸题..恩就是这个鬼卷积...放到某奇怪的OJ上供测试- -.

FWT的更多相关文章

  1. FWT与High dick(划掉改成Dimensional) Fourier Transform

    我们大家都知道xor卷积有个很好的做法:FWT.FWT的变换形式是很好看的 // 说明一下Vector可以向量化运算,也可以当做数组来slice与concat Vector tf(A,2^n){ Ve ...

  2. Codeforces663E Binary Table(FWT)

    题目 Source http://codeforces.com/contest/663/problem/E Description You are given a table consisting o ...

  3. HDU5909 Tree Cutting(树形DP + FWT)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5909 Description Byteasar has a tree T with n ve ...

  4. CROC 2016 - Final Round [Private, For Onsite Finalists Only] C. Binary Table FWT

    C. Binary Table 题目连接: http://codeforces.com/problemset/problem/662/C Description You are given a tab ...

  5. 卷积FFT、NTT、FWT

    先简短几句话说说FFT.... 多项式可用系数和点值表示,n个点可确定一个次数小于n的多项式. 多项式乘积为 f(x)*g(x),显然若已知f(x), g(x)的点值,O(n)可求得多项式乘积的点值. ...

  6. FWT 学习总结

    我理解的FWT是在二元运算意义下的卷积 目前比较熟练掌握的集合对称差卷积 对于子集卷积和集合并卷积掌握不是很熟练(挖坑ing) 那么就先来谈一谈集合对称差卷积吧 所谓集合对称差卷积 就是h(i)=si ...

  7. HDU 5823 color II(FWT)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5823 [题目大意] 定义一张无向图的价值:给每个节点染色使得每条边连接的两个节点颜色不相同的最少颜 ...

  8. hdu 5909 Tree Cutting [树形DP fwt]

    hdu 5909 Tree Cutting 题意:一颗无根树,每个点有权值,连通子树的权值为异或和,求异或和为[0,m)的方案数 \(f[i][j]\)表示子树i中经过i的连通子树异或和为j的方案数 ...

  9. 关于快速沃尔什变换(FWT)的一点学习和思考

    最近在学FWT,抽点时间出来把这个算法总结一下. 快速沃尔什变换(Fast Walsh-Hadamard Transform),简称FWT.是快速完成集合卷积运算的一种算法. 主要功能是求:,其中为集 ...

随机推荐

  1. HDU 1010 Tempter of the Bone(DFS+奇偶剪枝)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1010 题目大意: 输入 n m t,生成 n*m 矩阵,矩阵元素由 ‘.’ 'S' 'D' 'X' 四 ...

  2. GC算法

    http://www.brpreiss.com/books/opus5/html/page424.html http://www.brpreiss.com/books/opus5/html/page4 ...

  3. CentOS6.5个人目录下中文路径转英文路径

    如果安装了中文版到CentOS之后,root目录及home目录下会出现中文到路径名,如“桌面”.“文档”,“图片 .公共的” .“下载”. “音乐”.“ 视频”等目录,这样在命令行上操作十分到不方便. ...

  4. Podfile升级后的影响

    之前项目里用的Podfile都是版本 0.39 后面有一天电脑格盘重装以后cocoapods装的版本是 1.0.0.beta.6 那么问题来了,在下载或者clone一下项目后,经常是需要自己安装第三方 ...

  5. 开发Yii2过滤器并通过behaviors()行为调用

    在Yii2的几乎每个controller中,我们都会看到一个函数behaviors(),通常,我们用这个函数来配置控制器的权限,例如:public function behaviors()    {  ...

  6. Mysql分表和分区的区别、分库分表介绍与区别

    分表和分区的区别: 一,什么是mysql分表,分区 什么是分表,从表面意思上看呢,就是把一张表分成N多个小表,具体请看:mysql分表的3种方法 什么是分区,分区呢就是把一张表的数据分成N多个区块,这 ...

  7. CRect类

    类CRect是对Windows结构RECT的封装,凡是能用RECT结构的地方都可以用CRect代替. 结构RECT表示一个矩形的位置和尺寸,其定义为: typedef struct tagRECT{ ...

  8. 连接到kali linux服务器上的MySQL服务器错误

    前言:想把数据库什么的都放在虚拟机kali Linux里,但无奈出了好多错误. 首先:可以参照上一篇文章开启kali服务器端的远程连接功能,上一篇文章 然后:使用window端的sqlyog(MySQ ...

  9. [转载]onkeydown、onkeypress、onkeyup、onblur、o

    转载链接: http://blog.sina.com.cn/s/blog_697b2dc101014ktb.html onkeydown:按下任何键(字母.数字.系统.tab等)都能触发,且对于字母不 ...

  10. 【PHP面向对象(OOP)编程入门教程】14.final关键字的应用

    这个关键字只能用来定义类和定义方法, 不能使用final这个关键字来定义成员属性,因为final是常量的意思,我们在PHP里定义常量使用的是define()函数,所以不能使用final来定义成员属性. ...