Fast Walsh-Hadamard Transform (快速沃尔什变换)
来源:互联网 发布:矩阵分解 翻译 编辑:程序博客网 时间:2024/06/05 05:34
做了一下(bestcoder#88)HDU 5909 ,发现是个树形dp。不小心写歪了就吃一个TLE。这个树形dp的复杂度是O(n*m^2),其实这个复杂度也能卡过吧。听说这里可以将O(m^2)优化成O(m*logm),这里就用到了FWT,快速沃尔什变换,然而我并不懂。所以这几天看了下 Fast Walsh-Hadamard Transform ,感觉挺有趣的(骗你的),根据一位远古神犇的博客写了一些。
具体为什么是对的我还没有完全理清,大概就是个奇葩的构造吧……
Fast Walsh-Hadamard Transform 就是用于解决一类卷积问题的方法。大概如下:
其中指任一二元逻辑位运算。
一些基础的想法:
为了加速这个运算,我们还是需要用一些类似FFT的东西。
注意到位运算都是有位独立性的,那么每次我们只考虑某一位?
不妨假设:
那么,我们的目标就是求出:
假如构造了一个变换 ,满足:
且可以在较短时间内进行变换及其逆变换,那么我们的目标就可以实现了。
似乎便不能继续往下走了,那我们具体情况具体分析。
XOR
当指异或运算的时候,即 SRM518 Nim 那题中所需要的方法。
此时:
接下来怎么来找变换 ?其实我并不知道这个变换是怎么找到的(可能哪个无聊的正好构造出来了?或者从很小的情况中顺藤摸瓜出来了?)。
但是这个变换确实存在,且形式比较漂亮。
虽然不知道这个是怎么构造出来的,不过我们还是可以很轻易地验证的。
AND
当指与运算的时候,也是可以做的。
变换为:
同样轻易可验证。
OR
当指或运算的时候,可以类比于与运算的变换:
XNOR,NAND,NOR
当指异或非运算、与非运算、或非运算时。
我们可以将 直接用异或运算、与运算、或运算的方法求出来,然后将互反的两位交换即可。
代码:
这里只贴一个与运算的代码,别的运算都可以类似实现。
void FWT( ll X[], int l, int r, int v ) { if ( l == r ) return; int m = ( l + r ) >> 1; FWT( X, l, m, v ); FWT( X, m + 1, r, v ); FOR ( i, 0, m - l ) { X[ l + i ] += X[ m + 1 + i ] * v; }}
模板:
void FWT(int a[],int n) { for(int d=1;d<n;d<<=1) for(int m=d<<1,i=0;i<n;i+=m) for(int j=0;j<d;j++) { int x=a[i+j],y=a[i+j+d]; a[i+j]=(x+y)%mod,a[i+j+d]=(x-y+mod)%mod; //xor:a[i+j]=x+y,a[i+j+d]=(x-y+mod)%mod; //and:a[i+j]=x+y; //or:a[i+j+d]=x+y; } } void UFWT(int a[],int n) { for(int d=1;d<n;d<<=1) for(int m=d<<1,i=0;i<n;i+=m) for(int j=0;j<d;j++) { int x=a[i+j],y=a[i+j+d]; a[i+j]=1LL*(x+y)*rev%mod,a[i+j+d]=(1LL*(x-y)*rev%mod+mod)%mod; //xor:a[i+j]=(x+y)/2,a[i+j+d]=(x-y)/2; //and:a[i+j]=x-y; //or:a[i+j+d]=y-x; } } void solve(int a[],int b[],int n) { FWT(a,n); FWT(b,n); for(int i=0;i<n;i++) a[i]=1LL*a[i]*b[i]%mod; UFWT(a,n); }
2 0
- Fast Walsh-Hadamard Transform (快速沃尔什变换)
- Fast Walsh-Hadamard Transform (快速沃尔什变换)
- Fast Walsh-Hadamard Transform
- walsh-Hadamard变换
- walsh-Hadamard变换
- 快速傅立叶变换(Fast Fourier Transform)
- 快速傅立叶变换(Fast Fourier Transform)
- Fast Radial Symmetry Transform/快速径向对称变换
- Fast Radial Symmetry Transform/快速径向对称变换
- Fast Radial Symmetry Transform/快速径向对称变换(代码)
- HADAMARD变换
- Hadamard 变换
- Hadamard变换
- 3D数学之快速傅立叶变换(Fast Fourier Transform-FFT)
- C和FORTRAN的快速傅里叶/余弦/正弦变换(Fast Fourier/Cosine/Sine Transform)开源库分享
- FFT(Fast Fourier transform 快速傅里叶变换)
- DCT, DST, Walsh, Hadamard , Haar和Slant图像处理程序
- DCT, DST, Walsh, Hadamard , Haar和Slant图像处理程序
- 用OpenCV进行视频截取
- 操作系统:银行家算法(避免死锁)
- 安装.net framework 3.5出错 提示0x800f081f问题!
- maven阿里云中央仓库
- jdk安装注意事项
- Fast Walsh-Hadamard Transform (快速沃尔什变换)
- java线程
- AsyncTask用法总结(Android)
- 【EXPLAIN】“type”字段详解之MySQL官方文档翻译
- Android 项目目录结构
- java中不利用get方法获得私有属性、不利用set方法修改私有属性、通过执行私有方法getName获得私有属性、通过执行私有方法setName更改私有属性name的值
- 使用百度的Echart遇到的问题
- osgi
- C++11特性初探