快速沃尔什变换\(FWT\)

是一种可以快速完成集合卷积的算法。

什么是集合卷积啊?

集合卷积就是在集合运算下的卷积。比如一般而言我们算的卷积都是\(C_i=\sum_{j+k=i}A_j*B_k\),而集合卷积计算的就是\(C_i=\sum_{j\otimes k=i}A_j*B_k\),其中\(\otimes\)是一种集合运算,可以是与、或、异或。

类似于快速傅里叶变换\(FFT\),\(FWT\)也需要寻求一种变换方式\(FWT(A)\),使\(FWT(C)=FWT(A)*FWT(B)\),其中\(*\)运算就是数组对应下标相乘,时间复杂度是\(O(n)\)的。

或(or)运算的FWT

构造\(FWT(A)=A'\),其中\(A'[i]=\sum_{j\subseteq i}A[j]\)。

这样就能满足\(C'=A'*B'\)了。

如何构造?

考虑把\(A\)分成前后两段\(A_0,A_1\),假设\(A\)的长度为\(2^k\)。

那么\(A_0\)对应的二进制中第\(k-1\)位一定是\(0\),\(A_1\)对应的二进制中第\(k-1\)位一定是\(1\)。

所以\(FWT(A)=merge(FWT(A_0),FWT(A_1)+FWT(A_0))\),其中\(merge\)的意思是把前后两段拼接起来,因为前后两段的长度都是\(2^{k-1}\)。

至于\(IFWT?\)

倒推一下就好了。\(IFWT(A')=merge(IFWT(A'_0),IFWT(A'_1)-IFWT(A'_0))\)。

代码:

  1. void fwt_or(ll *P,int len,int opt){
  2. for (int i=1;i<len;i<<=1)
  3. for (int p=i<<1,j=0;j<len;j+=p)
  4. for (int k=0;k<i;++k)
  5. P[j+k+i]+=P[j+k]*opt;
  6. }

与(and)运算的FWT

与或同理。

构造\(FWT(A)=A'\),\(A'[i]=\sum_{i\subseteq j}A[j]\)。

\(FWT(A)=merge(FWT(A_0)+FWT(A_1),FWT(A_1))\)

\(IFWT(A')=merge(IFWT(A'_0)-IFWT(A'_1),IFWT(A'_1))\)。

代码:

  1. void fwt_and(ll *P,int len,int opt){
  2. for (int i=1;i<len;i<<=1)
  3. for (int p=i<<1,j=0;j<len;j+=p)
  4. for (int k=0;k<i;++k)
  5. P[j+k]+=P[j+k+i]*opt;
  6. }

异或(xor)运算的FWT

直接上结论吧。

\(FWT(A)=merge(FWT(A_0)+FWT(A_1),FWT(A_0)-FWT(A_1))\)

\(IFWT(A)=merge(\frac{IFWT(A'_0)+IFWT(A'_1)}{2},\frac{IFWT(A'_0)-IFWT(A'_1)}{2})\)。

证明出门右转

代码:

  1. void fwt(int *P,int len,int opt){
  2. for (int i=1;i<len;i<<=1)
  3. for (int p=i<<1,j=0;j<len;j+=p)
  4. for (int k=0;k<i;++k)
  5. {
  6. int x=P[j+k],y=P[j+k+i];
  7. P[j+k]=1ll*opt*(x+y)%mod;
  8. P[j+k+i]=1ll*opt*(x-y+mod)%mod;
  9. }
  10. }

如果是\(IFWT\)的话就让\(opt=\frac{mod+1}2\)就好了。

快速沃尔什变换FWT的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

  7. HDU 5977 Garden of Eden (树形dp+快速沃尔什变换FWT)

    CGZ大佬提醒我,我要是再不更博客可就连一月一更的频率也没有了... emmm,正好做了一道有点意思的题,就拿出来充数吧=.= 题意 一棵树,有 $ n (n\leq50000) $ 个节点,每个点都 ...

  8. BZOJ4589 Hard Nim(快速沃尔什变换FWT)

    这是我第一道独立做出来的FWT的题目,所以写篇随笔纪念一下. (这还要纪念,我太弱了) 题目链接: BZOJ 题目大意:两人玩nim游戏(多堆石子,每次可以从其中一堆取任意多个,不能操作就输).$T$ ...

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

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

随机推荐

  1. Android Studio 入门级教程

    引用原文:http://www.cnblogs.com/abao0/p/6934023.html 写博客是为了记住自己容易忘记的东西,另外也是对自己工作的总结,文章可以转载,无需版权.希望尽自己的努力 ...

  2. 文件(1)--File

    File简介 Java.io.File用于表示文件(目录),也就是说程序员可以通过File类在程序中操作硬盘上的文件和目录.File类只用于表示文件(目录)的信息(名称.大小等),不能对文件的内容进行 ...

  3. Spring -- spring 和 hibernate 整合

    1.概述, 事务管理, 编程式和说明式事务管理 2. 事务属性 传播行为: 传播行为 意义 PROPAGATION_MANDATORY 该方法必须运行在一个事务中.如果当前事务不存在,将抛出一个异常. ...

  4. Pandas系列

    系列(Series)是能够保存任何类型的数据(整数,字符串,浮点数,Python对象等)的一维标记数组.轴标签统称为索引. pandas.Series Pandas系列可以使用以下构造函数创建 - p ...

  5. JNIjw05

    ZC: 这个代码,没有真正的运行测试 1.VC6(CPP)的DLL代码: #include<stdio.h> #include "jniZ_JNIjw05.h" #in ...

  6. 求中位数,O(n)的java实现【利用快速排序折半查找中位数】

    查找无序数组的中位数,要想时间复杂度为O(n)其实用计数排序就能很方便地实现,在此讨论使用快速排序进行定位的方法. 1.中位数定义 2.算法思想 3.Java代码实现 4.时间复杂度分析 5.附录 中 ...

  7. Django进阶Model篇003 - 数据库同步技巧

    一.认识一个目录 目录名:migrations 作用:用来存放通过makemigrations命令生成的数据库脚本,不熟悉的情况下,里面生成的脚本不要轻易修改.app目录下必须要有migrations ...

  8. ddt读取json文件测试用例的执行顺序

    一. 源码的说明 在源码中,ddt的file_data函数下有这样一段话 意思是说,如果json文件的内容是字典,字典的键名将会作为测试用例名的后缀,字典的值将会作为测试数据,如果这样的话,如果键名字 ...

  9. st表模板

    http://blog.csdn.net/insistgogo/article/details/9929103 这篇博客讲解的很详细了,求区间最大值也可以用st表,时间复杂度O(n log(n)),查 ...

  10. Mac环境下Android Studio配置Git以及最基本使用

    Git是分布式版本管理工具,现在使用十分广泛,相对于SVN,GIT的使用更加方便,在离线环境下,仍然可以进行版本控制工作.且速度十分快.在Windows下,先需要自行安装Git程序,网址git-scm ...