[学习笔记]FWT——快速沃尔什变换
解决涉及子集配凑的卷积问题
一、介绍
1.基本用法
FWT快速沃尔什变换学习笔记
就是解决一类问题:
$f[k]=\sum_{i\oplus j=k}a[i]*b[j]$
基本思想和FFT类似。
首先转化成为另一个多项式$FWT(A),FWT(B)$
使得:$FWT(A\oplus B)=FWT(A)×FWT(B)$
这里,$×$是按位乘。这个是$O(n)$的。
然后,再$IFWT$回去即可。
类似于,直接过马路不好走。先从左边走上一座天桥,再从天桥走过去,再到马路右侧走下天桥。
就变成了$O(nlogn)$
$FWT$虽然不是非常容易理解,但是比较容易记忆。
(虽然一定要理解)
类比$FFT$的写法,就可以比较轻松记忆。
就是分治压缩、合并、分治解压的过程。
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#include<bits/stdc++.h>
#define reg register int
#define il inline
#define numb (ch^'0')
using namespace std;
typedef long long ll;
il void rd(int &x){
char ch;x=;bool fl=false;
while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
for(x=numb;isdigit(ch=getchar());x=x*+numb);
(fl==true)&&(x=-x);
}
il void prin(int x){
if(x/) prin(x/);
putchar(x%+'');
}
namespace Miracle{
const int N=+;
const int mod=;
const int inv2=;
int a[N],b[N];
int c[N],d[N];
int e[N];
int n;
void _or(int *f,int op){
for(reg p=;p<=n;p<<=){
int len=p/;
for(reg k=;k<n;k+=p){
for(reg l=k;l<k+len;++l){
if(op==)f[l+len]=(f[l+len]+f[l])%mod;
else f[l+len]=(f[l+len]-f[l]+mod)%mod;
}
}
}
}
void _and(int *f,int op){
for(reg p=;p<=n;p<<=){
int len=p/;
for(reg k=;k<n;k+=p){
for(reg l=k;l<k+len;++l){
if(op==)f[l]=(f[l+len]+f[l])%mod;
else f[l]=(f[l]-f[l+len]+mod)%mod;
}
}
}
}
void _xor(int *f,int op){
for(reg p=;p<=n;p<<=){
int len=p/;
for(reg k=;k<n;k+=p){
for(reg l=k;l<k+len;++l){
int x=f[l],y=f[l+len];
if(op==){
f[l]=(x+y)%mod;
f[l+len]=(x-y+mod)%mod;
}
else{
f[l]=(ll)(x+y)*inv2%mod;
f[l+len]=(ll)(x-y+mod)%mod*inv2%mod;
}
}
}
}
}
int main(){
scanf("%d",&n);
n=(<<n);
for(reg i=;i<n;++i) rd(a[i]),c[i]=a[i];
for(reg i=;i<n;++i) rd(b[i]),d[i]=b[i]; _or(c,);_or(d,);
for(reg i=;i<n;++i) e[i]=(ll)c[i]*d[i]%mod;
_or(e,-);
for(reg i=;i<n;++i){
prin(e[i]);putchar(' ');c[i]=a[i],d[i]=b[i];
}putchar('\n'); _and(c,);_and(d,);
for(reg i=;i<n;++i) e[i]=(ll)c[i]*d[i]%mod;
_and(e,-);
for(reg i=;i<n;++i){
prin(e[i]);putchar(' ');c[i]=a[i],d[i]=b[i];
}putchar('\n'); _xor(c,);_xor(d,);
for(reg i=;i<n;++i) e[i]=(ll)c[i]*d[i]%mod;
_xor(e,-);
for(reg i=;i<n;++i){
prin(e[i]);putchar(' ');//c[i]=a[i],d[i]=b[i];
}putchar('\n');
return ;
} }
int main(){
Miracle::main();
return ;
} /*
Author: *Miracle*
Date: 2018/11/22 15:08:15
*/
模板
2.子集卷积
https://www.cnblogs.com/Dance-Of-Faith/p/8818211.html
多加一维i,强制记录涉及集合sz大小
外层枚举sz
O(2^n*n^2)
(推荐使用FWT,因为比FMT常数小)
二、例题
留坑
[FWT] UOJ #310. 【UNR #2】黎明前的巧克力
三、FFT、NTT、FWT的比较
留坑
没啥可比较的。处理思路一致。
就是运算符的问题吧。
四、FWT、FMT的比较
留坑
FMT好写,FWT的与或卷积的第一步可以取代FMT
upda:2019.4.17
FMT可以代替FWT的与或卷积。IFMT把+改成-即可
(xor暂时不知道具体含义,估计也可以代替?)
实际上
FMT很辣鸡
相比之下,FWT做的事情完全包含FMT,并且常数是FMT的1/2!
[WC2018]州区划分(这个题我人傻常数大,必须用FWT卡常才能过)
所以还是写FWT吧
[学习笔记]FWT——快速沃尔什变换的更多相关文章
- FWT快速沃尔什变换学习笔记
FWT快速沃尔什变换学习笔记 1.FWT用来干啥啊 回忆一下多项式的卷积\(C_k=\sum_{i+j=k}A_i*B_j\) 我们可以用\(FFT\)来做. 甚至在一些特殊情况下,我们\(C_k=\ ...
- 浅谈算法——FWT(快速沃尔什变换)
其实FWT我啥都不会,反正就是记一波结论,记住就好-- 具体证明的话,推荐博客:FWT快速沃尔什变换学习笔记 现有一些卷积,形如 \(C_k=\sum\limits_{i\lor j=k}A_i*B_ ...
- Django RF:学习笔记(8)——快速开始
Django RF:学习笔记(8)——快速开始 安装配置 1.使用Pip安装Django REST Framework: pip install djangorestframework 2.在Sett ...
- [学习笔记]NTT——快速数论变换
先要学会FFT[学习笔记]FFT——快速傅里叶变换 一.简介 FFT会爆精度.而且浮点数相乘常数比取模还大. 然后NTT横空出世了 虽然单位根是个好东西.但是,我们还有更好的东西 我们先选择一个模数, ...
- 【学习笔记】快速傅里叶变换(FFT)
[学习笔记]快速傅里叶变换 学习之前先看懂这个 浅谈范德蒙德(Vandermonde)方阵的逆矩阵的求法以及快速傅里叶变换(FFT)中IDFT的原理--gzy hhh开个玩笑. 讲一下\(FFT\) ...
- 知识点简单总结——FWT(快速沃尔什变换),FST(快速子集变换)
知识点简单总结--FWT(快速沃尔什变换),FST(快速子集变换) 闲话 博客园的markdown也太傻逼了吧. 快速沃尔什变换 位运算卷积 形如 $ f[ i ] = \sum\limits_{ j ...
- [学习笔记] $FWT$
\(FWT\)--快速沃尔什变化学习笔记 知识点 \(FWT\)就是求两个多项式的位运算卷积.类比\(FFT\),\(FFT\)大多数求的卷积形式为\(c_n=\sum\limits_{i+j=n}a ...
- FWT快速沃尔什变换——基于朴素数学原理的卷积算法
这是我的第一篇学习笔记,如有差错,请海涵... 目录 引子 卷积形式 算法流程 OR卷积 AND卷积 XOR卷积 模板 引子 首先,考虑这是兔子 数一数,会发现你有一只兔子,现在,我再给你一只兔子 再 ...
- 初学FWT(快速沃尔什变换) 一点心得
FWT能解决什么 有的时候我们会遇到要求一类卷积,如下: Ci=∑j⊕k=iAj∗Bk\large C_i=\sum_{j⊕k=i}A_j*B_kCi=j⊕k=i∑Aj∗Bk此处乘号为普通乘法 ...
随机推荐
- Azure系列2.1.3 —— BlobEncryptionPolicy
(小弟自学Azure,文中有不正确之处,请路过各位大神指正.) 网上azure的资料较少,尤其是API,全是英文的,中文资料更是少之又少.这次由于公司项目需要使用Azure,所以对Azure的一些学习 ...
- Auzre系列1.1.1 —— 安装用于 IntelliJ 的 Azure 工具包
(文中大部分内容(95%)Azure官网上有,我只是把我自己实际操作中遇到的问题在这里阐述一下.) 先决条件 若要完成文章中的步骤,需要安装用于 IntelliJ 的 Azure 工具包,该工具包需要 ...
- POJ_1185_炮兵阵地 dp+状态压缩
题目:炮兵阵地 链接:http://poj.org/problem?id=1185 解题思路: 首先用 int 来表示每一行的情况,比如说第一行是k1,那么[ k1&(k1>>2) ...
- C# Note34: 异常机制相关小点
1.使用throw和throw ex抛出异常的区别 通常,我们使用try/catch/finally语句块来捕获异常,那么在抛出异常的时候,使用throw和throw ex有什么区别呢? 假如,按顺序 ...
- java.io.FileNotFoundException关于使用Intellij Idea时系统找不到指定文件的解决方案
第一种:Intellij Idea 这个智障编辑器 在用的时候 是你在这个web目录下的空文件夹他是不给你部署的 解决在空文件夹下面随便放个文件夹就行了 第二种:也是最笨的方法,但是有前提条件就是 你 ...
- Android——MaterialDesign之一Toolbar
Toolbar 由于ActionBar设计原因只能存在活动的顶部,从而不能实现MaterialDesign的效果,现在推荐使用Toolbar,继承Actionbar,但是比起它更加的灵活. 设置主题: ...
- php-memcached详解
一.memcached 简介 在很多场合,我们都会听到 memcached 这个名字,但很多同学只是听过,并没有用过或实际了解过,只知道它是一个很不错的东东.这里简单介绍一下,memcached 是高 ...
- jackson使用问题:mapper.readValue()将JSON字符串转反序列化为对象失败或异常
问题根源:转化目标实体类的属性要与被转JSON字符串总的字段 一 一对应!字符串里可以少字段,但绝对不能多字段. 先附上我这段出现了问题的源码: // 1.接收并转化相应的参数.需要在pom.xml中 ...
- python设计模式第二十天【模版方法模式】
1.应用场景 (1)具有相同的操作,但是步骤中具有不同的操作细节 2.代码实现 #!/usr/bin/env python #! _*_ coding:UTF-8 _*_ from abc impor ...
- 4.namespace
命名空间( namespace)是 Linux 内核的一个强大特性,为容器虚拟化的实现带来极大便 利. 利用这一特性,每个容器都可以拥有自己单独的命名空间,运行在其中的应用都像是在 独立的操作系统环境 ...