FWT-快速沃尔什变换

FWT有啥用啊

我们知道,FFT可以解决多项式的卷积,即

\[C_k=\sum_{i+j=k}A_i*B_j
\]

如果将操作符换一下,换成集合运算符

比如

\[C_k=\sum_{i|j=k}A_i*B_j\\\C_k=\sum_{i\&j=k}A_i*B_j\\\C_k=\sum_{i\oplus j=k}A_i*B_j
\]

这时就不能使用FFT

但是FFT使我们产生了一种想法

我们能不能用一种类似FFT的方法,用另一个多项式来表示\(A,B\),然后再对应相乘,最后再变换回来呢

答案是可以的,这就是FWT,即快速沃尔什变换

咋搞啊

我们以或运算举例:

我们按照定义,显然可以构造 \(FWT[A] = A' = \sum_{i=i|j}A_{j}\) ,来表示 \(j\) 满足二进制中 \(1\) 为 \(i\) 的子集。

那么显然会有 \(C_{i} = \sum_{i=j|k}A_{j}*B_{k} \Rightarrow FWT[C] = FWT[A] * FWT[B]\)

至于上面这个是怎么来的:

\[\begin{aligned}
FWT[C][i]&=FWT[A][i]*FWT[B][i]\\
\sum_{j|i}C_j&=(\sum_{j|i}A_j)*(\sum_{j|i}B_j) \\
\sum_{j|i}C_j&=\sum_{j|i,k|i} A_jB_k\\
\sum_{j|i}C_j&=\sum_{j|i}\sum_{a|b=j}A_aB_b\\
C_j&=\sum_{a|b=j}A_aB_b
\end{aligned}
\]

这样就和上面我们想要的式子一样了。

一堆定义/结论

别问我怎么推的,我也不知道。

这里有详细的证明。

通用性质

性质1:

\[FWT(A\pm B)=FWT(A)\pm FWT(B)
\]

性质2:

定义\(\oplus\)为任意集合运算

\[FWT(A\oplus B)=FWT(A)*FWT(B)\ \ (对应相乘)
\]

或运算

定义:

\[FWT(A)[i]=\sum_{j|i=i}A_j
\]

正向运算:

\[FWT(A)=\begin{cases}(FWT(A_0),FWT(A_1)+FWT(A_0))& n>1\\\ A & n=0\end{cases}
\]

逆向运算:

\[IFWT(A)=\begin{cases}(IFWT(A_0),IFWT(A_1)-IFWT(A_0))&n>1\\\ A&n=0\end{cases}
\]

与运算

定义:

\[FWT(A)[i]=\sum_{i\&j=j}A_i
\]

正向运算:

\[FWT(A)=\begin{cases}(FWT(A_0)+FWT(A_1),FWT(A_1))&n>1\\\ A &n=0\end{cases}
\]

逆向运算:

\[IFWT(A)=\begin{cases}(IFWT(A_0)-IFWT(A_1),IFWT(A_1))&n>1\\\ A&n=0\end{cases}
\]

异或运算

定义:

令\(d(x)\)为\(x\)在二进制下拥有的1的数量

\[FWT(A)[i]=\sum_{d(j\&i)为偶数}A_j-\sum_{d(k\&i)为奇数}A_k
\]

正向运算:

\[FWT(A)=\begin{cases}(FWT(A_0)+FWT(A_1),FWT(A_0)-FWT(A_1))&n>0\\\ A&n=0\end{cases}
\]

逆向运算:

\[IFWT(A)=\begin{cases}(\frac{IFWT(A_0+A_1)}{2},\frac{IFWT(A_0-A_1)}{2})&n>1\\\ A&n=0\end{cases}
\]

板子

  1. 按位或
  2. 按位与
  3. 按位异或
//by Harry_bh
void FWT1(long long a[],int len)
{
for(int mid=2;mid<=len;mid<<=1)
for(int i=0;i<len;i+=mid)
for(int j=i;j<i+(mid>>1);j++)a[j+(mid>>1)]+=a[j];
}
void IFWT1(long long a[],int len)
{
for(int mid=2;mid<=len;mid<<=1)
for(int i=0;i<len;i+=mid)
for(int j=i;j<i+(mid>>1);j++)a[j+(mid>>1)]-=a[j];
}
void FWT2(long long a[],int len)
{
for(int mid=2;mid<=len;mid<<=1)
for(int i=0;i<len;i+=mid)
for(int j=i;j<i+(mid>>1);j++)a[j]+=a[j+(mid>>1)];
}
void IFWT2(long long a[],int len)
{
for(int mid=2;mid<=len;mid<<=1)
for(int i=0;i<len;i+=mid)
for(int j=i;j<i+(mid>>1);j++)a[j]-=a[j+(mid>>1)];
}
void FWT3(long long a[],int len)
{
for(int mid=2;mid<=len;mid<<=1)
for(int i=0;i<len;i+=mid)
for(int j=i;j<i+(mid>>1);j++)
{
long long x=a[j],y=a[j+(mid>>1)];
a[j]=x+y,a[j+(mid>>1)]=x-y;
}
}
inline void IFWT3(long long a[],int len)
{
for(int mid=2;mid<=len;mid<<=1)
for(int i=0;i<len;i+=mid)
for(int j=i;j<i+(mid>>1);j++)
{
long long x=a[j],y=a[j+(mid>>1)];
a[j]=(x+y)>>1,a[j+(mid>>1)]=(x-y)>>1;
}
}

参考资料

LSJ-FWT

OI-WIKI

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

  1. FWT快速沃尔什变换学习笔记

    FWT快速沃尔什变换学习笔记 1.FWT用来干啥啊 回忆一下多项式的卷积\(C_k=\sum_{i+j=k}A_i*B_j\) 我们可以用\(FFT\)来做. 甚至在一些特殊情况下,我们\(C_k=\ ...

  2. [学习笔记]FWT——快速沃尔什变换

    解决涉及子集配凑的卷积问题 一.介绍 1.基本用法 FWT快速沃尔什变换学习笔记 就是解决一类问题: $f[k]=\sum_{i\oplus j=k}a[i]*b[j]$ 基本思想和FFT类似. 首先 ...

  3. 浅谈算法——FWT(快速沃尔什变换)

    其实FWT我啥都不会,反正就是记一波结论,记住就好-- 具体证明的话,推荐博客:FWT快速沃尔什变换学习笔记 现有一些卷积,形如 \(C_k=\sum\limits_{i\lor j=k}A_i*B_ ...

  4. 知识点简单总结——FWT(快速沃尔什变换),FST(快速子集变换)

    知识点简单总结--FWT(快速沃尔什变换),FST(快速子集变换) 闲话 博客园的markdown也太傻逼了吧. 快速沃尔什变换 位运算卷积 形如 $ f[ i ] = \sum\limits_{ j ...

  5. 初学FWT(快速沃尔什变换) 一点心得

    FWT能解决什么 有的时候我们会遇到要求一类卷积,如下: Ci=∑j⊕k=iAj∗Bk\large C_i=\sum_{j⊕k=i}A_j*B_kCi​=j⊕k=i∑​Aj​∗Bk​此处乘号为普通乘法 ...

  6. FWT快速沃尔什变换例题

    模板题 传送门 #include<bits/stdc++.h> #define ll long long #define max(a,b) ((a)>(b)?(a):(b)) #de ...

  7. FWT快速沃尔什变换——基于朴素数学原理的卷积算法

    这是我的第一篇学习笔记,如有差错,请海涵... 目录 引子 卷积形式 算法流程 OR卷积 AND卷积 XOR卷积 模板 引子 首先,考虑这是兔子 数一数,会发现你有一只兔子,现在,我再给你一只兔子 再 ...

  8. FWT快速沃尔什变换

    前言 学多项式怎么能错过\(FWT\)呢,然而这真是个毒瘤的东西,蒟蒻就只会背公式了\(\%>\_<\%\) 或卷积 \[\begin{aligned}\\ tf(A) = (tf(A_0 ...

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

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

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

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

随机推荐

  1. Python 多进程池

    def get_html(n): time.sleep(n) print("sub_progress success") return n # 多进程池 pool = multip ...

  2. JAVAWeb入门之JSP基础知识

    也是到了考试周,很多课都结了,准备去学点新东西.随后就开始自学JAVAWeb. 要学习JAVAWeb,首先需下面的知识: a)      HTML/CSS/JS(前端页面),XML,JSON,vue ...

  3. BCP 运行错误

    记录下使用bcp导出csv文件时的错误: [Microsoft][ODBC SQL Server Driver][SQL Server]对象名 '***'无效问题的解决方案器 我们要对student数 ...

  4. Java面试题:Java中的集合及其继承关系

    关于集合的体系是每个人都应该烂熟于心的,尤其是对我们经常使用的List,Map的原理更该如此.这里我们看这张图即可: 1.List.Set.Map是否继承自Collection接口? List.Set ...

  5. linux内核级同步机制--futex

    在面试中关于多线程同步,你必须要思考的问题 一文中,我们知道glibc的pthread_cond_timedwait底层是用linux futex机制实现的. 理想的同步机制应该是没有锁冲突时在用户态 ...

  6. Java生鲜电商平台-库存管理设计与架构

    Java生鲜电商平台-库存管理设计与架构 WMS的功能: 1.业务批次管理 该功能提供完善的物料批次信息.批次管理设置.批号编码规则设置.日常业务处理.报表查询,以及库存管理等综合批次管理功能,使企业 ...

  7. Java生鲜电商平台-系统报表设计与架构

    Java生鲜电商平台-系统报表设计与架构 说明:任何一个运行的平台都需要一个很清楚的报表来显示,那么作为Java开源生鲜电商平台而言,我们应该如何设计报表呢?或者说我们希望报表来看到什么数据呢?   ...

  8. Python基础24

    import 与 from import 知乎上说的简洁明了,zhihu.com/question/38857862 from import, 导入之后就能拿来用了,直接用!到处用!

  9. Mysql使用ReplicationDriver驱动实现读写分离

    数据库的主从复制环境已经配好,该要解决系统如何实现读写分离功能了.Mysql的jdbc驱动提供了一种实现ReplicationDriver. 1 数据库地址的两种写法 参考:https://dev.m ...

  10. Freemarker简单封装

    Freemarker是曾经很流行的一个模板库,它是一种通用的模板库,不仅仅可以用来渲染html. 模板可以分为两类: 只能生成特殊类型文件的模板,如jinja.django.Thymeleaf.jad ...