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. canvas入门(画圆)

    1.想在H5上画一个canvas,必须在页面上你需要的地方添加canvas标签, <canvas id="myCanvas"></canvas>   接着需 ...

  2. Nginx报错403 forbidden (13: Permission denied)的解决办法

    由于开发需要,在本地环境中配置了LNMP环境,使用的是Centos 6.5 的yum安装,安装一切正常,但是由于默认网站文件夹比较奇葩,于是把网站文件用mv命令移动到了新的目录,并相应修改了配置文件, ...

  3. Swift学习二

    // 定义枚举方式一 enum Season { // 每个case定义一个实例 case Spring case Summer case Fall case Winter } // 定义枚举方式二 ...

  4. Java并发编程核心方法与框架-exchanger的使用

    Exchanger可以使两个线程之间传输数据,比生产者/消费者模式使用wait/notify更加方便. Exchanger中的exchange()方法具有阻塞的特点,此方法被调用后等待其他线程来取数据 ...

  5. SCP 命令(转)

    \ svn 删除所有的 .svn文件 find . -name .svn -type d -exec rm -fr {} \; linux之cp/scp命令+scp命令详解   名称:cp 使用权限: ...

  6. JavaScript 中 的prototype和__proto__

    1.prototype是函数的一个属性(每个函数都有一个prototype属性),这个属性是一个指针,指向一个对象.它是显示修改对象的原型的属性. 2.__proto__是一个对象拥有的内置属性(请注 ...

  7. Mongodb3.0.6副本集+分片学习笔记

    一.使用问题记录 1. mongodb3.0.6使用mongostat参数 >./mongostat -h 127.0.0.1:27017 -u root -p 123456 /authenti ...

  8. java 的 AccessController.doPrivileged使用

    AccessController.doPrivileged意思是这个是特别的,不用做权限检查. 在什么地方会用到呢:加入1.jar中有类可以读取一个文件,现在我们要使用1.jar去做这个事情.但是我们 ...

  9. Linux服务器管理: 日志管理(二)

    日志的轮替 1.日志文件的命名规则 a.如果配置文件中拥有"dateext"参数,那么日志会用日期来作为日志文件的后缀,例如:"secure-20150630" ...

  10. ExtJS请求验证方法

    //登录连接数据库验证 function loginCheck() { var UserName = Ext.getCmp("UserName").getValue(); var ...