小 Tips:在计算机语言中 \(\cap\) = & / and, \(\cup\) = | / or

First. 定义

定义长度为 \(2^n\) 的序列的 and 卷积 \(A = B * C\) 为 \(A_i=\sum_{j \cap k = i}{B_j \times C_k}\)

考虑快速计算

Second. 变换

定义长度为 \(2^n\) 的序列的 Zeta 变换

\[\hat A_i = \sum_{j \subseteq i}{A_j}
\]

即子集和

它具有一下性质:

\[\hat B_i \times \hat C_i
= \sum_{j \subseteq i} B_j \times \sum_{k \subseteq i} C_k
= \sum_{p \subseteq i} \sum_{j \cap k = p} B_j \times C_k
= \sum_{p \subseteq i} A_p = \hat A_i
\]

相当于 FFT 中的点值表示法,用以加速卷积过程

Third. 快速变换

暴力求解 \(\hat A\) 最优时间复杂度为 \(3^n\),考虑加速

考虑 子集DP ,有一篇很好的博客[1],这里大概讲解一下。

其实 \(\hat A\) 本质上是一个高维( \(n\) 维)前缀和

如果我们要求二维前缀和,显然可以通过一下代码实现:

// 1st
for(int i=1; i<=n; ++i)
for(int j=1; j<=m; ++j)
a[i][j]+=a[i-1][j];
// 2nd
for(int i=1; i<=n; ++i)
for(int j=1; j<=n; ++j)
a[i][j]+=a[i][j-1];

我们发现 1st 完成后 a[i][j] 表示的是 \(\sum_{k \le i} a_{k,j}\),即 \((i,j)\) 上方的元素和

那么 2nd 便是将 \((i,j)\) 左边操作后的 \(\sum_{k \le j} a_{i,k}\) 累加到 a[i][j] 中,即完成二维前缀和


下面拓展到三维前缀和

// 1st
for(int i=1; i<=n; ++i)
for(int j=1; j<=n; ++j)
for(int k=1; k<=n; ++k)
a[i][j][k]+=a[i-1][j][k];
// 2nd
for(int i=1; i<=n; ++i)
for(int j=1; j<=n; ++j)
for(int k=1; k<=n; ++k)
a[i][j][k]+=a[i][j-1][k];
// 3rd
for(int i=1; i<=n; ++i)
for(int j=1; j<=n; ++j)
for(int k=1; k<=n; ++k)
a[i][j][k]+=a[i][j][k-1];

类似地,1st,2nd 中处理除了第 k 平面中的二维前缀和,3rd 在立体空间中把他们加起来,成为三维前缀和


回到 Zeta 变换

\[\hat A_i = \sum_{j \subseteq i}{A_j}
\]

如果我们用二进制 \((x_{n-1}x_{n-2}x_{n-3}\ ...\ x_2x_1x_0)_2\) 表示集合 \(i\),二进制 \((y_{n-1}y_{n-2}y_{n-3}\ ...\ y_2y_1y_0)_2\) 表示集合 \(j\)

那么 \(\hat A_i\) 可以被视为 \(n\) 维前缀和,即

\[\hat A_i = \sum_{y_{n-1}\le x_{n-1},y_{n-2}\le x_{n-2},\ ...,\ y_1\le x_1,y_0\le x_0} A_j
\]

当然,下标都为 0/1

因此,我们有如下 Code:

for(int i=0; i<n; ++i)
for(int j=0; j<(1<<n); ++j)
if(j&(1<<i))
a[j]+=a[j^(1<<i)];

以上 Code 的 naive 形式为:

for(int i1=0; i1<2; ++i1) for(int i2=0; i2<2; ++i2) ... for(int in=0; in<2; ++in) if(i1>0) a[i1][i2][...][in]+=a[i1-1][i2][...][in];
for(int i1=0; i1<2; ++i1) for(int i2=0; i2<2; ++i2) ... for(int in=0; in<2; ++in) if(i2>0) a[i1][i2][...][in]+=a[i1][i2-2][...][in];
...
for(int i1=0; i1<2; ++i1) for(int i2=0; i2<2; ++i2) ... for(int in=0; in<2; ++in) if(in>0) a[i1][i2][...][in]+=a[i1][i2][...][in-1];

不要质疑我代码编译不通过

因此,我们用 \(O(n2^n)\) 的时间复杂度解决了 Zeta 变换

Fourth. 逆变换

warning:此处不是 莫比乌斯反演

众所周知,前缀和的逆运算即为差分

我们发现,只需要先将最后一维差分,即可将序列处理为 \(n-1\) 维前缀和

for(int i1=0; i1<2; ++i1) for(int i2=0; i2<2; ++i2) ... for(int in=0; in<2; ++in) if(in>0) a[i1][i2][...][in]-=a[i1][i2][...][in-1];
...
for(int i1=0; i1<2; ++i1) for(int i2=0; i2<2; ++i2) ... for(int in=0; in<2; ++in) if(i2>0) a[i1][i2][...][in]-=a[i1][i2-2][...][in];
for(int i1=0; i1<2; ++i1) for(int i2=0; i2<2; ++i2) ... for(int in=0; in<2; ++in) if(i1>0) a[i1][i2][...][in]-=a[i1-1][i2][...][in];

但实际上因为前缀和都是无序的,因此我们直接正着做就可以啦

只需要把正变换的 += 改为 -= 就可以了

Fifth. 扩展

有时候,题目给的不是 \(\cap\) ,而是 \(\cup\) 怎么办?

那我们重定义 Zeta 变换 为:

\[\hat A_i = \sum_{i \supseteq j} A_j
\]

再推一下式子:

\[\hat B_i \times \hat C_i
=\sum_{i\supseteq j} B_j \times \sum_{i\supseteq k} C_k
=\sum_{i\supseteq j,i\supseteq k} B_j \times C_k
=\sum_{i\supseteq p} \sum_{j \cup k=p} B_j \times C_k
=\sum_{i\supseteq p} A_p
=\hat A_i
\]

变换即超集和,高维后缀和

求法也很简单,只用将源代码中的 if(j&(1<<i)) 该为 if(!(j&(1<<i))) 即可


是 \(\oplus\) 怎么办?

快去学 FWT 吧

Last. 例题

再送你一个并/交集的小口诀:下并或,上交与


  1. 高维前缀和总结(sosdp) - heyuhhh - 博客园 (cnblogs.com)

Fast Möbius Transform 学习笔记 | FMT的更多相关文章

  1. ios 控件代码transform学习笔记

    1.图片设置(平移,缩放,旋转) 创建一个transform属性 //按钮点击时,只能执行一次向上旋转 //派 M_PI_4 45度旋转 . CGAffineTransform transforms= ...

  2. css笔记 - transform学习笔记(二)

    transform转换 CSS transform 属于2D/3D上的转换.变形效果.他不是一个动画,他就是变形.比如正方形变平行四边形,再变圆形.都是形状变成另一个形状. 但是如果配合上transi ...

  3. FMT/FWT学习笔记

    目录 FMT/FWT学习笔记 FMT 快速莫比乌斯变换 OR卷积 AND卷积 快速沃尔什变换(FWT/XOR卷积) FMT/FWT学习笔记 FMT/FWT是算法竞赛中求or/and/xor卷积的算法, ...

  4. 「学习笔记」Fast Fourier Transform

    前言 快速傅里叶变换(\(\text{Fast Fourier Transform,FFT}\) )是一种能在\(O(n \log n)\)的时间内完成多项式乘法的算法,在\(OI\)中的应用很多,是 ...

  5. [原创]java WEB学习笔记52:国际化 fmt 标签,国际化的总结

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

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

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

  7. [学习笔记] 多项式与快速傅里叶变换(FFT)基础

    引入 可能有不少OIer都知道FFT这个神奇的算法, 通过一系列玄学的变化就可以在 $O(nlog(n))$ 的总时间复杂度内计算出两个向量的卷积, 而代码量却非常小. 博主一年半前曾经因COGS的一 ...

  8. Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第十八章:立方体贴图

    原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第十八章:立方体贴图 代码工程地址: https://github.c ...

  9. 快速傅里叶变换(FFT)学习笔记(其一)

    再探快速傅里叶变换(FFT)学习笔记(其一) 目录 再探快速傅里叶变换(FFT)学习笔记(其一) 写在前面 为什么写这篇博客 一些约定 前置知识 多项式卷积 多项式的系数表达式和点值表达式 单位根及其 ...

  10. 【OI向】快速傅里叶变换(Fast Fourier Transform)

    [OI向]快速傅里叶变换(Fast Fourier Transform) FFT的作用 ​ 在学习一项算法之前,我们总该关心这个算法究竟是为了干什么. ​ (以下应用只针对OI) ​ 一句话:求多项式 ...

随机推荐

  1. 使用自签名证书在Docker中部署Asp.Net Core(Abp)项目

    一 编写Dockerfile文件 FROM mcr.microsoft.com/dotnet/aspnet:6.0 COPY / /app WORKDIR /app EXPOSE 80 ENTRYPO ...

  2. fs.1.10 ON CENTOS7 docker镜像制作

    概述 freeswitch是一款简单好用的VOIP开源软交换平台. centos7 docker上编译安装fs1.10版本的流程记录. 环境 docker engine:Version 24.0.6 ...

  3. S2DNAS:北大提出动态推理网络搜索,加速推理,可转换任意网络 | ECCV 2020 Oral

    S2DNAS最核心的点在于设计了丰富而简洁的搜索空间,从而能够使用常规的NAS方法即可进行动态推理网络的搜索,解决了动态推理网络的设计问题,可进行任意目标网络的转换   来源:晓飞的算法工程笔记 公众 ...

  4. KingbaseES V8R6 常用的系统函数

    查看当前日志文件lsn位置: select sys_current_wal_lsn(); 查看某个lsn对应的日志名: select sys_walfile_name('0/1162FBA0'); 查 ...

  5. 4 PyExecJS模块

    PyExecJS模块 pyexecjs是一个可以帮助我们运行js代码的一个第三方模块. 其使用是非常容易上手的. 但是它的运行是要依赖能运行js的第三方环境的. 这里我们选择用node作为我们运行js ...

  6. #dp#nssl 1478 题

    分析 设\(f[i]\)表示第\(i\)个是否幸存,\(dp[i][j]\)表示若第\(i\)个幸存,第\(j\)个是否必死 倒序枚举人,如果存在\(dp[i][a[x]],dp[i][b[x]]\) ...

  7. #矩阵树定理,高斯消元#洛谷 4111 [HEOI2015]小 Z 的房间

    题目 分析 题目要求生成树个数,求出基尔霍夫矩阵后高斯消元, 但是这里模数不是质数,所以要辗转相除法 代码 #include <cstdio> #include <cctype> ...

  8. OpenCV一句话将彩色图片(Mat)转换为灰度

    auto in_gray=cv::imdecode(in, cv::IMREAD_GRAYSCALE);

  9. 使用IDEA直接连接数据库报错:Server returns invalid timezone. Go to 'Advanced' tab and set 'serverTimezone' property manually.

    错误详情:使用IDEA直接连接数据库报错:Server returns invalid timezone. Go to 'Advanced' tab and set 'serverTimezone' ...

  10. 金融App面临安全风险?解锁HMS Core安全检测服务解决方案

    数字经济时代,金融类App成为人们理财.购买证券股票以及办理各项银行业务的重要载体.科技驱动着金融行业的转型升级,但在创新发展的同时,金融App面临的安全风险类型与场景也在持续增加.如何更好地规避安全 ...