FMT 与 子集(逆)卷积
本文参考了 Dance of Faith 大佬的博客
我们定义集合并卷积
\]
最暴力的时候只能 \(O(4^n)\) 完成,进行 一些优化 可以在 \(O(3^n)\) 内完成,当然我们可以在 \(O(n 2^n)\) 利用 \(FMT\) 或者 \(FWT\) 内快速处理。
\(FMT\) 原理更好理解,就介绍此种方式。
具体来说,类似与 \(FFT\) 我们把 \(f,g\) 求点值,然后点值相乘后再插值变化回去。因为要快速实现这个过程,我们可以考虑利用 快速莫比乌斯变换 和 快速莫比乌斯反演 实现。
定义
定义 \(f\) 的莫比乌斯变换 \(\hat{f}\) ,满足 \(\hat{f_S} = \sum_{T \subseteq S} f_T\) 。(也就是 \(\hat{f}\) 是原来函数 \(f\) 的子集和)
定义 \(\hat{f}\) 的莫比乌斯反演 \(f\) ,利用容斥原理可以得到 \(f_S = \sum_{T \subseteq S} (-1)^{|S| - |T|} f_{T}\) 。
考虑为什么这个形式满足集合并卷积。
\[h_{S} = \sum_{L \subseteq S}^{} \sum_{R \subseteq S}^{} [L \cup R = S] f_{L} * g_{R}
\]左右同时做莫比乌斯变换。
\[\begin{aligned}
\hat{h_{S}} &= \sum_{T \subseteq S} \sum_{L \subseteq T} \sum_{R \subseteq T} [L \cup R = T] f_{L} * g_{R}\\
&= \sum_{L \subseteq S} \sum_{R \subseteq S} [L \cup R \subseteq S] f_{L} * g_{R}
\end{aligned}
\]由于 \([L \cup R \subseteq S] = [L \subseteq S][R \subseteq S]\) ,也就有
\[\begin{aligned}
\hat{h_{S}} &= \sum_{L \subseteq S} \sum_{R \subseteq S} f_{L} * g_{R}\\
&= (\sum_{L \subseteq S}f_L)(\sum_{L \subseteq S}g_R)\\
&=\hat{f_L} * \hat{g_R}
\end{aligned}
\]证毕。
快速变换与反演
原理讲解
上面那两个集合和我们暴力做是 \(O(3^n)\) 的,可以进行优化。
考虑按 集合大小 分层递推。
令 \(\hat{f_{S}}^{(i)}\) 为 \(\sum_{T \subseteq S} [(S - T) \subseteq \{0, 1, 2, ..., i\}] f_{T}\) ,有 \(\hat{f}_S^{(0)} = f_S\) 。
那么对于不包含 \(\{i\}\) 的集合 \(S\) ,满足 \(\hat{f_{S}}^{(i)} = \hat{f_{S}}^{(i - 1)}\) ,那么它的贡献就是
\]
这样,递推 \(n\) 轮后 \(\hat{f}^{(n)}_S\) 就包含所有情况,即为所求变换。
对于莫比乌斯反演的话,同样递推,不断减掉就行了。
代码实现
void FMT(int *f, int opt) {
for (int j = 0; j < n; ++ j)
for (int i = 0; i < (1 << n); ++ i) if (i >> j & 1)
f[i] += opt * f[i ^ (1 << j)];
}
子集卷积
原理讲解
我们定义 \(f\) 与 \(g\) 的子集卷积 \(f * g = h\) 。
\]
其实就是
\]
刚刚讲的子集并卷积为何不行呢?因为有 \([L \cap R = \varnothing]\) 的这个限制。
如何去掉这个限制呢,我们多记一维集合大小,也就是 \(f_{i, S}\) 表示有 \(i\) 个元素,集合表示为 \(S\) 。
显然当且仅当 \(i = |S|\) 时是正确的,我们先做 \(FMT\) 。
所以递推的时候就是 \(h_{i + j, S} = \sum_{i, j} f_{i, S} * g_{j, S}\) ,其实是个多项式乘法。
由于前面对于 \(n\) 个函数进行 \(FMT\) 需要 \(O(n^2 2^n)\) 的复杂度。
这里 \(FFT\) 也优化不了复杂度(而且由于常数会慢很多),那么直接暴力卷积就好了。
代码实现
for (int i = 0; i <= n; ++ i) {
for (int j = 0; i + j <= n; ++ j)
for (int S = 0; S < (1 << n); ++ S)
h[i + j][S] += f[i][S] * g[j][S];
}
最后我们要求 \(S\) 的子集卷积的结果,直接用 \(h_{\text{bitcount(S)}, S}\) \(IFMT\) 的。
子集逆卷积
原理讲解
我们有时候需要做子集卷积意义下的除法或者相关运算。
比如对于两个函数 \(f * g = h\) ,我们已知 \(g, h\) 要求 \(f\) 。
那么就是 \(f = h * g^{-1}\) 。其实就是要求 \(g^{-1}\) 在子集卷积意义下的结果。
同样我们只需要考虑 \(FMT\) 之后的结果。
由于对于每一位我们做的是多项式下的乘法。其实就是对于每一位求的 \(g^{-1}\) 就是多项式求逆后的结果。
同样对于别的运算也是多项式后的结果。
但是写那个 \(O(n \log n)\) 的倍增多项式求逆显然十分地麻烦,可以考虑 \(O(n ^ 2)\) 递推。
令 \(g^{-1} = t\) 假设我们求出 \(t_{0, 1, \cdots, i - 1}\) ,要求 \(t_i\) 。\((t_0 = g_0^{-1})\) 。
我们可以把 \(g_i\) 减去 \(t\) 和 \(g\) 前 \(i - 1\) 项做卷积后的第 \(i\) 项的值,就是所求的 \(t_i\) 。
这样就可以解决啦qwq
代码
inline void Inv(int *f) {
tmp[0] = fpm(f[0], Mod - 2);
for (int i = 0; i <= n; ++ i) {
inv[i] = tmp[i];
for (int j = 0; i + j <= n; ++ j)
tmp[i + j] -= inv[i] * f[j];
}
}
FMT 与 子集(逆)卷积的更多相关文章
- FMT 和 子集卷积
FMT 和 子集卷积 FMT 给定数列 $ a_{0\dots 2^{k}-1} $ 求 $ b $ 满足 $ b_{s} = \sum_{i\in s} a_i $ 实现方法很简单, for( i ...
- 逆卷积的详细解释ConvTranspose2d(fractionally-strided convolutions)
1.首先先定义进行卷积的参数: 输入特征图为高宽一样的Hin*Hin大小的x 卷积核大小kernel_size 步长stride padding填充数(填充0) 输出特征图为Hout*Hout大小的y ...
- @总结 - 2@ 位运算卷积/子集卷积 —— FWT/FMT
目录 @0 - 参考资料@ @1 - 异或卷积概念及性质@ @2 - 快速沃尔什正变换(异或)@ @3 - 快速沃尔什逆变换(异或)@ @4 - 与卷积.或卷积@ @5 - 参考代码实现@ @6 - ...
- [学习笔记&教程] 信号, 集合, 多项式, 以及各种卷积性变换 (FFT,NTT,FWT,FMT)
目录 信号, 集合, 多项式, 以及卷积性变换 卷积 卷积性变换 傅里叶变换与信号 引入: 信号分析 变换的基础: 复数 傅里叶变换 离散傅里叶变换 FFT 与多项式 \(n\) 次单位复根 消去引理 ...
- [WC2018]州区划分(状压DP+FWT/FMT)
很裸的子集反演模板题,套上一些莫名其妙的外衣. 先预处理每个集合是否合法,再作显然的状压DP.然后发现可以写成子集反演的形式,直接套模板即可. 子集反演可以看这里. 子集反演的过程就是多设一维代表集合 ...
- LOJ #2542. 「PKUWC 2018」随机游走(最值反演 + 树上期望dp + FMT)
写在这道题前面 : 网上的一些题解都不讲那个系数是怎么推得真的不良心 TAT (不是每个人都有那么厉害啊 , 我好菜啊) 而且 LOJ 过的代码千篇一律 ... 那个系数根本看不出来是什么啊 TAT ...
- 『TensotFlow』转置卷积
网上解释 作者:张萌链接:https://www.zhihu.com/question/43609045/answer/120266511来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业 ...
- pytorch 不使用转置卷积来实现上采样
上采样(upsampling)一般包括2种方式: Resize,如双线性插值直接缩放,类似于图像缩放,概念可见最邻近插值算法和双线性插值算法——图像缩放 Deconvolution,也叫Transpo ...
- 卷积生成对抗网络(DCGAN)---生成手写数字
深度卷积生成对抗网络(DCGAN) ---- 生成 MNIST 手写图片 1.基本原理 生成对抗网络(GAN)由2个重要的部分构成: 生成器(Generator):通过机器生成数据(大部分情况下是图像 ...
随机推荐
- Azure WebJob-Custom Schedule for Azure Web Job Timer Triggers
如果想实现Azure Schedule WebJob,有两种方法: 1. 配置CRON Expression,网上有在线CRON配置工具,根据业务需要配置即可 注意:Azure的CRON Expres ...
- C++ 文件操作(简易的学籍管理系统)
这是一个简易的学籍管理系统,大一时居然三个人写了一千多行......年少无知啊!欢迎摘果实! 1 #include <iostream> #include <fstream> ...
- python(day16)内置函数,匿名函数
# add = lambda x,y:x+y # print(add(1,2)) # dic={'k1':10,'k2':100,'k3':30} # def func(key): # return ...
- [Web][DreamweaverCS6][高中同学毕业分布去向网站+服务器上挂载]一、安装与破解DreamweaverCS6+基本规划
DreamweaverCS6安装与破解 一.背景介绍:同学毕业分布图项目计划简介 哎哎哎,炸么说呢,对于Web前端设计来说,纯手撕html部分代码实在是难受. 对于想做地图这类的就“必须”用这个老工具 ...
- 一天一个Linux命令--find
文件查找:(以find为主) which:查找命令字所在的位置 locate:模糊匹配(只要包含关键字的文件都查找出来) 不是实时的,基于数据库查找, updatedb升级loca ...
- new 和 newInstance 的区别
初始化一个类,生成一个实例的时候:newInstance() 和 new 有什么区别? 用newInstance与用new是区别的,区别在于创建对象的方式不一样,前者是使用类加载机制,那么为什么会有两 ...
- 设置TextBlock默认样式后,其他控件的Text相关属性设置失效问题
问题: 定义了默认TextBlock样式后,再次自定义下拉框 or 其他控件 ,当内部含有TextBlock时,设置控件的字体相关样式无效,系统始终使用TextBlock设置默认样式 解决方案: 为相 ...
- React.js开发的基本配置(配了两天)
记录下心酸的过程: 1.安装npm 安装node.js,这时候你就可以使用npm了. 因为官方的源下载npm的包比较慢,所以可以用淘宝的源,这时候使用nrm来进行npm源的切换 在cmd中执行 npm ...
- ios和安卓H5交互桥接
ios交互 demo1(摘自网络) <!doctype html> <html> <head> <meta charset="UTF-8" ...
- axios请求本地的json文件在打包部署到子目录域名下,路径找不到
前言: 因为要同时部署两个项目,有一个是部署到域名下面的子目录下,如:https://xxx.com/siot-admin vue 项目中使用axios请求了本地项目的static文件夹下的json文 ...