本文参考了 Dance of Faith 大佬的博客

我们定义集合并卷积

\[h_{S} = \sum_{L \subseteq S}^{} \sum_{R \subseteq S}^{} [L \cup R = S] f_{L} * g_{R}
\]

最暴力的时候只能 \(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)}\) ,那么它的贡献就是

\[\hat{f}_{S \cup \{i\}}^{(i)} = \hat{f}_{S}^{(i - 1)} + \hat{f}_{S \cup \{i\}}^{(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\) 。

\[h_{S} = \sum_{L \subseteq S}^{} \sum_{R \subseteq S}^{} [L \cup R = S, L \cap R = \varnothing] f_{L} * g_{R}
\]

其实就是

\[h_S = \sum_{T \subseteq S} f_T * g_{S - T}
\]

刚刚讲的子集并卷积为何不行呢?因为有 \([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 与 子集(逆)卷积的更多相关文章

  1. FMT 和 子集卷积

    FMT 和 子集卷积 FMT 给定数列 $ a_{0\dots 2^{k}-1} $ 求 $ b $ 满足 $ b_{s} = \sum_{i\in s} a_i $ 实现方法很简单, for( i ...

  2. 逆卷积的详细解释ConvTranspose2d(fractionally-strided convolutions)

    1.首先先定义进行卷积的参数: 输入特征图为高宽一样的Hin*Hin大小的x 卷积核大小kernel_size 步长stride padding填充数(填充0) 输出特征图为Hout*Hout大小的y ...

  3. @总结 - 2@ 位运算卷积/子集卷积 —— FWT/FMT

    目录 @0 - 参考资料@ @1 - 异或卷积概念及性质@ @2 - 快速沃尔什正变换(异或)@ @3 - 快速沃尔什逆变换(异或)@ @4 - 与卷积.或卷积@ @5 - 参考代码实现@ @6 - ...

  4. [学习笔记&教程] 信号, 集合, 多项式, 以及各种卷积性变换 (FFT,NTT,FWT,FMT)

    目录 信号, 集合, 多项式, 以及卷积性变换 卷积 卷积性变换 傅里叶变换与信号 引入: 信号分析 变换的基础: 复数 傅里叶变换 离散傅里叶变换 FFT 与多项式 \(n\) 次单位复根 消去引理 ...

  5. [WC2018]州区划分(状压DP+FWT/FMT)

    很裸的子集反演模板题,套上一些莫名其妙的外衣. 先预处理每个集合是否合法,再作显然的状压DP.然后发现可以写成子集反演的形式,直接套模板即可. 子集反演可以看这里. 子集反演的过程就是多设一维代表集合 ...

  6. LOJ #2542. 「PKUWC 2018」随机游走(最值反演 + 树上期望dp + FMT)

    写在这道题前面 : 网上的一些题解都不讲那个系数是怎么推得真的不良心 TAT (不是每个人都有那么厉害啊 , 我好菜啊) 而且 LOJ 过的代码千篇一律 ... 那个系数根本看不出来是什么啊 TAT ...

  7. 『TensotFlow』转置卷积

    网上解释 作者:张萌链接:https://www.zhihu.com/question/43609045/answer/120266511来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业 ...

  8. pytorch 不使用转置卷积来实现上采样

    上采样(upsampling)一般包括2种方式: Resize,如双线性插值直接缩放,类似于图像缩放,概念可见最邻近插值算法和双线性插值算法——图像缩放 Deconvolution,也叫Transpo ...

  9. 卷积生成对抗网络(DCGAN)---生成手写数字

    深度卷积生成对抗网络(DCGAN) ---- 生成 MNIST 手写图片 1.基本原理 生成对抗网络(GAN)由2个重要的部分构成: 生成器(Generator):通过机器生成数据(大部分情况下是图像 ...

随机推荐

  1. Oracle DB 12c first glance

    单机上装了个12c,只看了看EM的界面……

  2. Building QGIS from source - step by step(随笔3)

    依赖包安装 在编译QGIS前分别需要利用cygwin和OSGeo4W 安装网站上的依赖库.分别需要安装的依赖库可以参考官网,此外对应版本的ygwin和OSGeo4W 也可以在网站上找到下载链接. ht ...

  3. arcgis for js开发之路径分析

    arcgis for js开发之路径分析 //方法封装 function routeplan(x1, x2, y1, y2, barrierPathArray, isDraw, callback) { ...

  4. scrollTo不起作用

    最近,我在HorizontalScrollview中使用scrollTo不起作用? ...... 以上省略N个字. 我只想说: 在使用scrollTo的时候,要先保证该HorizontalScroll ...

  5. Docker+Redis镜像的原理以及部署安装(超详解附截图)

    文章来源:公众号-智能化IT系统. 一. DOCKER介绍 Docker简介 (1)Docker 是一个开源的应用容器引擎,基于 Go 语言,并遵从Apache2.0协议开源. (2)Docker 可 ...

  6. Linux中Apache服务器的简单配置

    配置Apache服务器: 1.安装Apache,可以参考Linux 中yum的配置来安装: yum install http* -y 2.修改SELinux: setenforce 0 查看: 3.防 ...

  7. Linux简单配置SendMail发送邮件

    本文简单整理了一下如何在Linux服务器上安装.配置SendMail发送邮件的步骤,此文不是配置邮件服务器,具体测试环境为CentOS Linux release 7.2.1511 (Core) ,如 ...

  8. DBA思考系列——凛冬将至,丧钟为谁而鸣!

    诸多迹象昭示着凛冬将至,大萧条终于正式在全国各地拉开了序幕,很多80后的国人没有经历过苦日子,也没有经历过真正的金融危机.这场经济危机必将摧毁一些无视经济能力,盲目购房,盲目消费的家庭或个人.个人对经 ...

  9. TableExistsException: hbase:namespace

    解决:zookeeper还保留着上一次的Hbase设置,所以造成了冲突.删除zookeeper信息,重启之后就没问题了 1.切换到zookeeper的bin目录: 2.执行$sh zkCli.sh 输 ...

  10. Unknown column 'user_uid' in 'field list' sql错误解决过程

    在idea中运行一直有错,找了好多个地方都找不到,以为是我的字段名字写错了,然而都是对的. 把错误的这个字段删了再打一遍就好了,