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. ajax成功跨域_自己写的

    跨域的简单原理:一般浏览器会阻止js请求异端服务器(A服务器请求B服务器).js连接却除外 如:<script type="text/jscript" src="h ...

  2. 用淘宝ip地址库查ip

    这是一个通过调用淘宝ip地址库实现ip地址查询的功能类 using System; using System.Collections.Generic; using System.Linq; using ...

  3. 居于Web的进度条实现思路(下载百分比)

    http://www.cnblogs.com/wfyfngu/p/4866434.html 在传统桌面项目中,进度条随处可见,但作为一个很好的用户体验,却没有在如今主流的B/S程序中得到传承,不能不说 ...

  4. 使用Java练习算法常用的基本操作

    一.使用Java练习算法常常需要使用控制台的数据输入和输出,下面记录一下基本的使用方法: 基本用法 import java.util.*; public class Main { public sta ...

  5. Linux命令之dos2unix

    Linux命令之dos2unix (2011-09-22 11:24:06) 转载▼ 标签: 杂谈   Linux命令之dos2unix - 将DOS格式文本文件转换成UNIX格式 用途说明 dos2 ...

  6. thinkphp 项目分组 -开发随笔1

    php中变量的声明, 和变量的初始化 是结合在一起的, 要声明变量, 就是通过初始化变量来实现的. 感觉页面版式的布局, 还是: 先大致规划出布局, 如两栏 三栏, 一览的左右上下结合, 搭配. 然后 ...

  7. Linux关于添加硬盘的那些事儿:笔记

    添加新硬盘:http://note.youdao.com/share/?id=8cf27602cdce36e1d4160f00e9004b00&type=note 关于添加硬盘的那些事儿:   ...

  8. 安装windows后重新修复grub2的引导

    前段时间,我的用的双系统windows8.1 + fedora 21 workstation,使用grub2引导fedora和windows8.1的启动.由于一些原因,导致我的windows8.1无法 ...

  9. C#委托全解析

    什么是委托?                                                                                       委托类似于C语 ...

  10. 论在Windows下远程连接Ubuntu

       Ubuntu下1:下载xrdp   sudo apt-get install xrdp 2: urs/share/applications 下找到  远程桌面 设置成这样 Windows下 1; ...