最近在学FWT,抽点时间出来把这个算法总结一下。

  快速沃尔什变换(Fast Walsh-Hadamard Transform),简称FWT。是快速完成集合卷积运算的一种算法。

  主要功能是求:,其中为集合运算符。

  就像FFT一样,FWT是对数组的一种变换,我们称数组X的变换为FWT(X)。

  所以FWT的核心思想是:

    为了求得C=A★B,我们瞎搞搞出一个变换FWT(X),

    使得FWT(C)=FWT(A)  FWT(B),然后根据FWT(C)求得C。

    (其中★表示卷积运算,表示将数组对应下标的数相乘的运算)

    也就是说我们可以通过FWT(X)变换把复杂度O(n^2)的★运算变为O(n)的运算。

  跟FFT是完全相同的。所以我们考虑怎么搞出这个FWT(X)。

  与运算(&)和或运算(|)最容易理解,我们先讲讲这两个怎么搞。我们以或运算为例。

  若 x | y = z,那么x和y一定满足二进制中的1为z的子集。

  所以我们可以令FWT(A)=A',其中。(“i | j = i”就是表示“j满足二进制中的1为i的子集”)

  (虽然以上两行根本构不成逻辑,但是请相信这个定义就是正确的)

  于是我们就有C'=A'  B',从这些数组的定义来看,这个式子确实是正确的。

  然后我们就要研究一下FWT(A)也就是A'怎么求。当然不能枚举 i 的子集,这样复杂度太高。

  既然是二进制的,我们不妨考虑用分治进行计算。(为毛是二进制就要用分治啊喂!)

  我们设A0为A的前一半,A1为A的后一半,如果A的长度为2^k,那么A0、A1的长度为2^(k-1)。

  如果我们知道了FWT(A0)和FWT(A1),那么FWT(A)是不是就可以求了呢?当然可以。

    FWT(A)的前一半相当于二进制位的第k位填了0,那么是它子集的仍然只有FWT(A0) (它本身);

    FWT(A)的后一半相当于二进制位的第k位填了1,那么是它子集的不仅仅有FWT(A1) (它本身),还有FWT(A0)。

  那么转移就出来了,

  其中merge(X,Y)为X和Y两个数组接在一起,  表示将数组对应下标的数相加的运算。

  这样我们就在O(2^k*k)也就是O(nlogn)的时间内求出了FWT(A)。

  还有一个问题,我们怎么通过FWT(C)求得C?

  这不就是FWT()的逆变换吗?根据转移方程,你难道不会倒着推回来吗?

  这其实就相当于你知道了A0'、A1',然后要求得A0、A1。

  因为我们已经知道了A0'=A0,A1'=A1+A0,所以我们就有A0=A0',A1=A1'-A0'。

  所以:

    

  既然知道了或运算,与运算也是一样的,因为与运算和或运算本质是相同的。

  读者可以试着自己推一遍,再继续往下看:

    

    

  然后就是鬼畜的异或,先说结论:

    

    

  一种比较靠谱的说法是,其中d(x)为x的二进制中1的个数。

  先想一想再往下看吧~

  然后你可能会想,与和或本质上不是相同的吗?

  然后就有,其中d'(x)为x的二进制中0的个数。

  然后就有

      

  然后结果是一毛一样的。

  (其实就是把整个数组倒过来而已)

  所以又回到FWT的核心思想:

    为了求得C=A★B,我们瞎搞搞出一个变换FWT(X),

    使得FWT(C)=FWT(A)  FWT(B),然后根据FWT(C)求得C。

  所以我们只要找到运算中,数字x的一个特征FWT(x),满足FWT(x  y)=FWT(x)*FWT(y)。这个特征就是FWT啦~

  怎么样,是不是给你一种“我上我也行”的感觉?

  然后你试图寻求异或FWT的更简单的公式:

  然后你开始脑补:

  然后惊喜地发现正好满足 FWT(C)=FWT(A)  FWT(B) !

  然后你开始写转移公式:

    

    

    

  (以上18行都是小C在口胡)

  到底有没有靠谱的做法呢?小D说他有一种解方程的做法。

  为了不失一般性,假设A、B、C数组的长度为2。C=A★B,为异或卷积运算。

  然后显然C[0] = A[0]*B[0] + A[1]*B[1]  , C[1] = A[0]*B[1] + A[1]*B[0]。

  然后我们开始变形了!由于(我们猜想)FWT(A)一定是a*FWT(A0) + b*FWT(A1)的形式,所以:

    设A'[0] = a*A[0] + b*A[1],A'[1] = c*A[0] + d*A[1]。

    B和C同理,因为小C知道列一大堆方程出来肯定没人看所以小C就不列出来了。

  然后就有C'[0] = A'[0]*B'[0]。解方程,得:

  因为a,b不同时等于0,所以a=1,b=±1。同理,c=1,d=±1。

  (由于解方程过程中有很多槽点所以小C也不能保证正确性)

  然后究竟是+1还是-1呢?小D给的说法是“枚举,check一下”。

  check个鬼啊(╯‵□′)╯︵┻━┻!这个做法槽点真的太多了好吗?

  不过能够得出正确答案是真的。

关于快速沃尔什变换(FWT)的一点学习和思考的更多相关文章

  1. 一个数学不好的菜鸡的快速沃尔什变换(FWT)学习笔记

    一个数学不好的菜鸡的快速沃尔什变换(FWT)学习笔记 曾经某个下午我以为我会了FWT,结果现在一丁点也想不起来了--看来"学"完新东西不经常做题不写博客,就白学了 = = 我没啥智 ...

  2. 【学习笔鸡】快速沃尔什变换FWT

    [学习笔鸡]快速沃尔什变换FWT OR的FWT 快速解决: \[ C[i]=\sum_{j|k=i} A[j]B[k] \] FWT使得我们 \[ FWT(C)=FWT(A)*FWT(B) \] 其中 ...

  3. 快速沃尔什变换FWT

    快速沃尔什变换\(FWT\) 是一种可以快速完成集合卷积的算法. 什么是集合卷积啊? 集合卷积就是在集合运算下的卷积.比如一般而言我们算的卷积都是\(C_i=\sum_{j+k=i}A_j*B_k\) ...

  4. 集合并卷积的三种求法(分治乘法,快速莫比乌斯变换(FMT),快速沃尔什变换(FWT))

    也许更好的阅读体验 本文主要内容是对武汉市第二中学吕凯风同学的论文<集合幂级数的性质与应用及其快速算法>的理解 定义 集合幂级数 为了更方便的研究集合的卷积,引入集合幂级数的概念 集合幂级 ...

  5. 快速沃尔什变换 FWT 学习笔记【多项式】

    〇.前言 之前看到异或就担心是 FWT,然后才开始想别的. 这次学了 FWT 以后,以后判断应该就很快了吧? 参考资料 FWT 详解 知识点 by neither_nor 集训队论文 2015 集合幂 ...

  6. Codeforces 662C(快速沃尔什变换 FWT)

    感觉快速沃尔什变换和快速傅里叶变换有很大的区别啊orz 不是很明白为什么位运算也可以叫做卷积(或许不应该叫卷积吧) 我是看 http://blog.csdn.net/liangzhaoyang1/ar ...

  7. 快速沃尔什变换(FWT)学习笔记 + 洛谷P4717 [模板]

    FWT求解的是一类问题:\( a[i] = \sum\limits_{j\bigoplus k=i}^{} b[j]*c[k] \) 其中,\( \bigoplus \) 可以是 or,and,xor ...

  8. 快速沃尔什变换 (FWT)学习笔记

    证明均来自xht37 的洛谷博客 作用 在 \(OI\) 中,\(FWT\) 是用于解决对下标进行位运算卷积问题的方法. \(c_{i}=\sum_{i=j \oplus k} a_{j} b_{k} ...

  9. 快速沃尔什变换(FWT) 与 快速莫比乌斯变换 与 快速沃尔什变换公式推导

    后面的图片将会告诉: 如何推出FWT的公式tf 如何推出FWT的逆公式utf 用的是设系数,求系数的方法! ============================================== ...

随机推荐

  1. 201621123043 《Java程序设计》第7周学习总结

    1. 本周学习总结 2.书面作业 1. GUI中的事件处理 1.1 写出事件处理模型中最重要的几个关键词. 事件:用户的操作. 事件源:产生事件的组件. 事件监听程序:对事件进行处理的操作所引发的相关 ...

  2. python API的安全认证

    我们根据pid加客户端的时间戳进行加密md5(pid|时间戳)得到的单向加密串,与时间戳,或者其它字段的串的url给服务端. 服务端接收到请求的url进行分析 客户端时间与服务端的时间戳之差如果大于规 ...

  3. fflush(stdin)与fflush(stdout)

    1.fflush(stdin): 作用:清理标准输入流,把多余的未被保存的数据丢掉.. 如: int main() { int num; char str[10]; cin>>num; c ...

  4. vivado License导入方法与资源获取

    前言 以下安装说明基于已经正确安装vivado 笔者操作环境:linux vivado版本:2015.2 vivado License导入方法: 点击菜单栏[Help],选择[Manage Licen ...

  5. SUN平台服务器光纤共享存储互斥失败如何恢复数据?

    服务器数据恢复故障描述: 服务器最初的设计思路为将两台SPARC SOLARIS系统通过光纤交换机共享同一存储作为CLUSTER使用,正常情况下A服务器工作,当A服务器发生故障宕机后即可将其关机然后开 ...

  6. iOS 11 导航栏 item 偏移问题 和 Swift 下 UIButton 设置 title、image 显示问题

    html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,bi ...

  7. JAVA_SE基础——15.循环嵌套

    嵌套循环是指在一个循环语句的循环体中再定义一个循环语句结构,while,do-while,for循环语句都可以进行嵌套,并且可以互相嵌套,下面来看下for循环中嵌套for循环的例子. 如下: publ ...

  8. ASP.NET MVC中错误处理方式

    /// <summary> /// 标记了HandleError,并指明错误处理页为AboutError.aspx /// </summary> /// <returns ...

  9. 第5章 子网划分和CIDR

    第5章 子网划分和CIDR 划分网络 根据A类.B类或C类网络ID来识别网段具有一些局限性,主要是在网络级别之下不能对地址空间进行任何逻辑细分 如果一个IP是一个A类网络.数据报到达网关,然后传输到9 ...

  10. 非PE病毒介绍

    1.宏病毒 1.1 介绍 本文中的宏特制office系列办公软件中的宏,Microsoft Office中对宏的定义为"宏就是能够组织在一起的,可以作为一个独立命令来执行的一系列Word 命 ...