集合幂级数笔记
符号声明:\(\subseteq\) 表示包含于,\(\subsetneq\) 表示真包含于。
定义
我们令 \(U=\{0,\dots,n-1\}\)。
一个集合幂级数 \(f\) 是对于全集 \(U\) 和域 \(R\),一个 \(f:2^U\to R\) 的映射,对于 \(S \subseteq U\),记 \(f_{S}\) 表示 \(S\) 所对应的值。
所谓域就是含有 \(0,1\) 且对于四则运算封闭的数集。
例如 \(\mathbb{Q},\mathbb{Q}(\sqrt{2})=\{a+b\sqrt{2}\mid a,b \in \mathbb{Q}\}\) 都是域。
在 OI 中,一般取对质数 \(P\) 取模的 \(\mathbb{F}_P\)。
也写作
这里的 \(x^{S}\) 完全是形式记号,这个写法仿照了形式幂级数,但不应该看作一个关于 \(x\) 的函数。
运算
我们需要运算,首先和差加法逆是好定义的。
对于两个集合幂级数 \(f,g\),定义它们的和 \(f+g\) 为
对于集合幂级数 \(f\),定义加法逆 \(-f\) 为
对于集合幂级数 \(f,g\),定义减法 \(f-g\) 为
接下来考虑两个集合幂级数的乘法,也就是卷积。
我们知道,对于两数列 \(a,b\),其卷积 \(f\circ g=c\) 为
这里我们可以把 \(x+y=i\) 看成一个抽象的形式,即对于任意二元函数 \(\operatorname{op}(x,y)\),我们都可以定义
为 \(a,b\) 的某种卷积。
普通序列卷积中,这个运算是加法,对于集合我们尝试定义「加法」,我们考虑并。
这样就得到了集合并卷积,如果用二进制数表示集合,看起来就像是 OR 运算,所以也称 OR 卷积。
求集合并卷积是简单的,定义 \(\operatorname{FMT}(f)_S=\sum_{T \subseteq S}f_T\),不难有
对于多个的 OR 卷积,容易发现可以先全部 FMT,乘起来后再逆 FMT。
FMT 的求法是简单的,考虑高维前缀和。
对于逆 FMT,我们要用到子集反演:
证明:
子集卷积
接下来是重要的子集卷积,我们定义
这里 \(\sqcup\) 意思是无交并。
这看起来比较困难,因为我们并不能通过一个简单的变换将其转化成逐位相乘。
但是注意到 \(L\sqcup R=S\Leftrightarrow L\cup R=S\land |L|+|R|=|S|\),我们可以将 \(R\) 替换为 \(R[x]\),对于 \(S\),定义新的 \(f^{\prime}_S=f_S x^{|S|}\)。
那么我们可以对这样替换后的 \(f^{\prime},g^{\prime}\) 做一遍 OR 卷积,然后对于每个 \(S\),只取 \(|S|\) 次的系数。
多项式乘法朴素实现是 \(n^2\) 的,于是复杂度 \(\Theta(n^22^n)\) 当然你也可以用 FFT,但是在 \(n\) 较小时常数是更劣的。
集合幂级数复合(exp,ln,求逆)
接下来我们定义 \(k\) 次幂为 \(f^k=\underbrace{f\times f \dots \times f}_{k \text{个} f}\),对于一个形式幂级数 \(h(x)\),定义复合
是一个集合幂级数。
我们注意到两个性质(记 \(f^{\prime}\) 表示之前我们替换后的结果)
于是 \((h(f))^{\prime}_S=h(f^{\prime}_S)\)。
我们可以先将 \(f\) 转成 \(f^{\prime}\),对于每一个 \(f^{\prime}_S\) 计算 \(h(f^{\prime}_S)\),省略 \(n\) 次以上的项,再取出 \([x^{|S|}]h(f^{\prime}_S)\)。
根据最新科技,多项式复合在 \(\mathbb{F}_{998244353}\) 下可以做到 \(\Theta(n \log^2 n)\),我们得到 \(\Theta(n \log^2 n 2^n)\) 的集合幂级数复合。
当然实际上用不着这个对于 \(h(x)=\exp(x)\) 和 \(\ln(1+x)\) 以及 \(\dfrac{1}{1-x}\) 的情况下,直接 \(\Theta(n^2)\) 求就可以了。
呃,怎么 \(\Theta(n^2)\) exp,ln,求逆?
如果你不知道什么是 exp,ln,求逆
如何 exp,ln,求逆
求逆
给你 \(A\),要求
于是
ln
\(B(x)=\ln A(x)\),于是 \(B^{\prime}(x)=\dfrac{A^{\prime}(x)}{A(x)}\),可以直接求逆再积分。
但这样子常数太大,我们可以直接递推
exp
\(B(x)=\exp(A(X))\),于是 \(B^{\prime}(x)=A^{\prime}(x)B(x)\)。
部分 exp
我们定义 \(\exp_k(x)=\sum_{i=0}^{k}\dfrac{x^i}{i!}\)。
令 \(C(x)=\dfrac{A(x)^k}{k!}\)(不难直接求得)
其中 exp 是有重要的组合意义的,其表示将一个集合无序拆分成若干子集,所有拆分方案的权值和。
你已经掌握了集合幂级数的基础知识,接下来是一些练习。
一般记 \(e(S)\) 表示在一个图中 \(S\) 的导出子图边数,\(e(S,T)\) 表示所有 \(u \in S,v\in T\) 的边 \((u,v)\) 数量(一般假设 \(S\cap T=\varnothing\)),在无向图中,有 \(e(S,T)=e(S\cup T)-e(S)-e(T)\)。
数连通生成子图
给你一个无向图 \(G=(V,E)\),求连通生成子图数量。
做法
似乎并不好直接刻画连通性,但我们知道
假设我们已经知道了对于点集 \(S\) 内部的连通生成子图数,令 \(g\) 表示 \(S\) 内部生成子图数,有
反过来就有 \(f=\ln g\),而 \(g_S=2^{e(S)}\),直接做集合幂级数 ln 即可。
这里有一个启示,对于生成子图,我们一般考虑将其组合得到简单的,再反过来推导。
数连通二分生成子图 at_arc205_f
给你一个图 \(G=(V,E)\),求有多少个连通的生成子图是二分图。
解法
注意到
染色是为了保证只计数一次。
令 \(g_S\) 表示 \(S\) 以内二分生成子图且染色的方案数,\(f_S\) 表示 \(S\) 以内连通二分生成子图且染色的方案数,所求即 \(\sum_{S \subseteq U}\dfrac{f_S}{2}\)。
考虑如何求 \(g\)。
有
直接子集卷积。
数 DAG 定向(CF1193A 略改)
给你一个无向图 \(G=(V,E)\),你需要对每条边定向,使得定向后图为 DAG。
做法
令 \(f_S\) 表示将 \(S\) 的导出子图内所有边定向且为 DAG 的方案数。
考虑枚举出度为 \(0\) 的点集 \(T\),首先 \(T\) 要为独立集,然后所有从 \(S\setminus T\) 到 \(T\) 的边的方向被唯一确定,似乎有
但这显然是错的,因为我们会重复计数,对于恰有 \(|T|\) 个点为出度为 \(0\) 点的情况下,会被重复计数 \(2^|S|-1\) 次。
考虑容斥,我们添加上容斥系数 \((-1)^{|T|-1}\),容易证明恰被计数一次。
这样朴素做是 \(\Theta(3^n)\) 的,无法通过。
这个转移是半在线的,后面会讲如何做半在线子集卷积,但这里可以直接推式子。
我们记 \(g_S=[S\text{ 是独立集且非空}](-1)^{|S|-1}\) 那么有
于是有 \(f=\dfrac{1}{1-g}\),直接求逆即可。
数强连通生成子图 CTT2014 D1T2 主旋律
给你一个有向图,求有多少个生成子图强连通。
做法
考虑一个想法,用 \(2^m\) 减去所有有两个强连通分量的子图。
那么假设已经知道好了强连通分量的划分,那么内部就是强连通子图,外部就是 DAG 子图计数。
设 \(\mathrm{ans}_S\) 为 \(S\) 为点集的生成子图个数,\(\mathrm{cof}_S\) 为将 \(S\) 划分为若干无出度强连通分量的所有方案的带权求和,权重为 \((-1)^{\mathrm{sz}-1}\),\(\mathrm{sz}\) 为划分出的强连通分量数。
根据之前的容斥,我们有
数点双连通生成子图
给你一个无向图 \(G=(V,E)\),求点双连通生成子图数量。
做法
我们考虑如何从点双连通分量得到连通图。
你可能会考虑耳分解之类的东西,但其实很简单。
我们依此扫每个点,每次将所有包含该点的点双连通分量合并就能得到连通图。
容易发现这是一一对应的。
假设我已经知道了对于每个点集 \(S\),点双连通生成子图的个数 \(f_S\),然后我们扫 \(i=1\dots n\),每一次操作就是取出所有包含 \(i\) 的点集 \(S\),去掉 \(i\) 之后进行 exp,然后再加回 \(i\) 放回 \(f\)。这被称作点双连通-连通变换。
我们考虑逆操作,取出所有包含 \(i\) 的点集 \(S\),去掉 \(i\) 之后 ln,加上 \(i\) 再放回去。
单次 ln 是 \(O(n^2 2^n)\) 的,复杂度 \(\Theta(n^3 2^n)\)。
数边双连通生成子图
给你一个无向图 \(G=(V,E)\),求边双连通生成子图数量。
做法1
我们可以这么刻画边双连通图。
- 点双大小不为 2 的连通图。
于是我们可以先求出点双连通生成子图数,然后去掉大小为 2 的,反过来再跑一遍正的,复杂度 \(\Theta(n^3 2^n)\)。
做法2
上面这个做法不够通用,我们尝试给出所谓边双连通-连通变换。
首先对于一张连通无向图,如果将所有边双缩起来,图会形成一棵树,树上的边是原图的割边。
考虑一个反过来的问题:假设给原图所有子集 \(S\subseteq U\) 均赋了权重 \(a_S\),并定义一张连通子图的权值是其所有边双对应的 \(a\) 之积,并且我们还已经对所有 \(S\) 知道了 \(S\) 的边双连通生成子图数量是 \(b_S\),如何求原图所有生成子图的权值和。
我们仿照之前思路,依次加点,每一次考虑所有编号 \(\le i\) 的 \(S\) 的生成子图的割边,再将所有经当前考虑的割边所连接的边双合并。
设考虑到 \(u\) 时的集合幂级数为 \(p_u\),首先 \((p_0)_S=a_Sb_S\)。
那么考虑由 \(p_{u-1}\) 转移到 \(p_u\),即加入所有两端编号最大值为 \(u\) 的割边。
先考虑加之前,此时对于点集 \(S\) 被分为 \(P_1,P_2,\dots,P_k\) 几块,假设 \(u \in P_1\)。
那么对于这样一个划分,贡献为
半在线卷积
有的时候我们并不能直接求逆解决,这时我们需要半在线。
例题 P4221 州区划分
\(n\) 座城市,每座城市有 \(w_i\) 人口,你要有序划分成若干州 \(\{V_1,\dots,V_k\}\),每个州非空且导出子图不是欧拉图,定义一个州的满意度为
定义一个划分方案的权值为所有州满意度的乘积。
求所有划分方案的权值和。
解法
首先欧拉图的限制是无关紧要的,直接判就可以了。
直接令 \(W_S=(\sum_{u \in S}w_u)^p\),有转移
这里很烦的是带了一个 \(\dfrac{1}{W_S}\) 导致不能直接写成集合幂级数的形式。
回顾一下怎么求子集卷积的,每个 \(S\) 上维护了一个多项式,注意到子集卷积时每项次数只会变大。
于是我们枚举次数 \(0\dots n\),每次跑一个 OR 卷积就可以了。

浙公网安备 33010602011771号