FMT/FWT学习笔记
FMT/FWT学习笔记
FMT/FWT是算法竞赛中求or/and/xor卷积的算法,数据处理中也有应用。
网上的命名方法有很多。
这里我们选这个博客的,把AND/OR命名为FMT,XOR命名为FWT
如果是整数,我们认为\(\cup\)和\(\cap\)运算是二进制下的,也就是\(\text{|和&}\),这可以帮我们理解之后的集合幂级数。
FMT 快速莫比乌斯变换 OR卷积
与FMT可以求出
\]
因为前缀的并是前缀,容易得到过程是把A、B求子集前缀和,得到FMTor数组
\]
与FFT类似,FMTor数组直接乘起来就得到了C的FMTor数组,证明如下:
\]
最后换回去(子集和变原数组)就得到了C
至于具体怎么算前缀和,挂张图,想必大家见过很多次了吧(箭头表示加法)
如上图,讨论这一层的1在不在下一个集合即可。
代码:
const int N = 2e5+200;
const ll mod = 998244353;
int a[N];
void FMTor(int *a,int n,int opt){
for(int l=2;l<=n;l<<=1){
int m=l>>1;
for(int *g=a;g!=a+n;g+=l){
for(int k=0;k<m;k++){
if(opt==1) g[k+m]=(g[k+m]+g[k])%mod;
else g[k+m]=(g[k+m]-g[k]+mod)%mod;
}
}
}
}
跟FFT非常的像...
AND卷积
\]
然后猜测FMTand为后缀和(后缀的交为后缀),
\]
同样的,证明:
\]
和OR是不是有几分相似?
const int N = 2e5+200;
const ll mod = 998244353;
int a[N];
void FMTand(int *a,int n,int opt){
for(int l=2;l<=n;l<<=1){
int m=l>>1;
for(int *g=a;g!=a+n;g+=l){
for(int k=0;k<m;k++){
if(opt==1) g[k]=(g[k]+g[k+m])%mod;
else g[k]=(g[k]-g[k+m]+mod)%mod;
}
}
}
}
快速沃尔什变换(FWT/XOR卷积)
这个稍微难点
我们要求
\]
这里的FWT数组不是那么显然,考虑构造。
由于线性相关,令
\]
那么
\]
带入C的定义,
\]
对比系数,
\]
异或有一系列性质:
\((j\cap x)\oplus (k\cap x)=(j\oplus k)\cap x\)
不知道这个的可以讨论一波:在第\(i\)位,
\[\begin{array}{|c|c|c|c|c|c|c|c|}j & k &x &j\cap x &k\cap x&(j\cap x)\oplus (k\cap x)&j \oplus k&(j\oplus k)\cap x\\0&0&0&0&0&0&0&0\\0&0&1&0&0&0&0&0\\0&1&0&0&0&0&1&0\\0&1&1&0&1&1&1&1\\1&0&0&0&0&0&1&0\\1&0&1&1&0&1&1&1\\1&1&0&1&1&0&0&0\\1&1&1&1&1&0&0&0\\\end{array}
\]异或前后1的个数奇偶性不变(对吧)
那么我们定义\(|x|\)为二进制下集合大小,即1的个数,g就可以赋值了
\]
\]
考虑怎么递推算这个东西,考虑加不加上区间长度i
由于枚举i为2的次幂从小到大,新加上i集合大小一定加一,系数乘负一,否则不变。
那么有:
\]
反过来,解方程可以得到
\]
代码:
const int N = 2e5+200;
const int mod = 998244353;
const int inv2 = 499122177;
int a[N];
void FWT(int *a,int n,int opt){
for(int l=2;l<=n;l<<=1){
int m=l>>1;
for(int *g=a;g!=a+n;g+=l){
for(int k=0;k<m;k++){
ll t=g[k+m];
g[k+m]=(g[k]-g[k+m]+mod)%mod;
g[k]=(g[k]+t)%mod;//草,有蝴蝶变换内味了
//提醒一下这和FFT的区别:没有乘单位根
if(opt==-1) g[k]=1ll*g[k]*inv2%mod,g[k+m]=1ll*g[k+m]*inv2%mod;
//而且反演的时候也不一样
}
}
}
}
就愉快地学完啦!是不是比FFT简单
FMT/FWT学习笔记的更多相关文章
- FWT学习笔记
FWT学习笔记 引入 一般的多项式乘法是这样子的: \(c_i=\sum_{i,j}a_j*b_k*[j+k==i]\) 但是如果我们将这个乘法式子里面的+号变换一下变成其他的运算符号呢? \(c_i ...
- 一个数学不好的菜鸡的快速沃尔什变换(FWT)学习笔记
一个数学不好的菜鸡的快速沃尔什变换(FWT)学习笔记 曾经某个下午我以为我会了FWT,结果现在一丁点也想不起来了--看来"学"完新东西不经常做题不写博客,就白学了 = = 我没啥智 ...
- FWT 学习笔记
FWT学习笔记 好久以前写的,先粘上来 定义数组 \(n=2^k\) \(A=[a_0,a_1,a_2,a_3,...,a_{n-1}]\) 令\(A_0=[a_0,a_1,a_2,...,a_{\f ...
- $\text {FWT}$学习笔记
\(\text {FWT}\) 学习笔记 正常项的\(\text {FWT}\) 在\(\text {OI}\)中,我们经常会碰到这种问题: 给出一个长度为\(n\)的序列\(a_{1,2,...,n ...
- 快速沃尔什变换 (FWT)学习笔记
证明均来自xht37 的洛谷博客 作用 在 \(OI\) 中,\(FWT\) 是用于解决对下标进行位运算卷积问题的方法. \(c_{i}=\sum_{i=j \oplus k} a_{j} b_{k} ...
- 快速沃尔什变换 FWT 学习笔记【多项式】
〇.前言 之前看到异或就担心是 FWT,然后才开始想别的. 这次学了 FWT 以后,以后判断应该就很快了吧? 参考资料 FWT 详解 知识点 by neither_nor 集训队论文 2015 集合幂 ...
- 快速沃尔什变换(FWT)学习笔记 + 洛谷P4717 [模板]
FWT求解的是一类问题:\( a[i] = \sum\limits_{j\bigoplus k=i}^{} b[j]*c[k] \) 其中,\( \bigoplus \) 可以是 or,and,xor ...
- 卷积理论 & 高维FWT学习笔记
之前做了那么多生成函数和多项式卷积的题目,结果今天才理解了优化卷积算法的实质. 首先我们以二进制FWT or作为最简单的例子入手. 我们发现正的FWT or变换就是求$\hat{a}_j=\sum_{ ...
- [学习笔记]FWT——快速沃尔什变换
解决涉及子集配凑的卷积问题 一.介绍 1.基本用法 FWT快速沃尔什变换学习笔记 就是解决一类问题: $f[k]=\sum_{i\oplus j=k}a[i]*b[j]$ 基本思想和FFT类似. 首先 ...
随机推荐
- 超过百万的StackOverflow Flutter 问题
老孟导读:今天分享StackOverflow上高访问量的20大问题,这些问题给我一种特别熟悉的感觉,我想你一定或多或少的遇到过,有的问题在stackoverflow上有几十万的阅读量,说明很多人都遇到 ...
- Solr复杂查询一:函数查询
一.简介 Solr的函数可以动态计算每个文档的值,而不是返回在索引阶段对应字段的静态数值集.函数查询是一类特殊的查询,它可以像关键词一样添加到查询中,对所有文档进行匹配并返回它们的函数计算值作为文档得 ...
- Docker之hello world
Docker Hello World Docker 允许你在容器内运行应用程序, 使用 docker run 命令来在容器内运行一个应用程序. 输出Hello world runoob@runoob: ...
- Linux C++ 网络编程学习系列(1)——端口复用实现
Linux C++ 网络编程学习系列(1)--端口复用实现 源码地址:https://github.com/whuwzp/linuxc/tree/master/portreuse 源码说明: serv ...
- Java成长记录第二集--基础重点
第一篇写的博客给自己的学习路线立了个flag后,感觉现在学习的积极性大增,这也离不开那几位老铁们的互相鼓励.废话不多说,现在给出自己总结的Java基础部分所要重点注意的内容,对以后的开发工作也是很常用 ...
- AJ学IOS(19)UI之QQ好友列表
AJ分享,必须精品 先看效果图 哈哈,这次猫猫给来个动态的图片,这个看起来带劲 实现思路 首先建立模型 这里用到的是一个双层的模型. cell的实现 这里一看其实就知道是一个tableView,我们自 ...
- Spring Boot 集成 Spring Security 入门案例教程
前言 本文作为入门级的DEMO,完全按照官网实例演示: 项目目录结构 Maven 依赖 <parent> <groupId>org.springframework.boot&l ...
- V - Infinite Prefixes CodeForces - 1295B math
天哪!!菜到家啦. 数学+思维. 首先求出一个周期内cnt0-cnt1=c的个数,如果C=0,那么只要在一个周期内有前缀等于x,那么答案就是-1,否则答案就是0 如果C!=0,列一下方程x=t*c+a ...
- python基础-json、pickle模块
json.pickle区别 总结: """ json: 1.不是所有的数据类型否可以序列化,序列化返回结果为字符串 2.不能多次对同一文件序列化 3.json数据可以跨语 ...
- [YII2] 视图层过滤客户恶意代码
两种方式: 一种是吧html的恶意标签转译:(注意的就是命名空间) <?php use yii\helpers\Html; ?> <h1><?=Html::encode( ...