集合幂级数笔记

符号声明:\(\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\)

也写作

\[\sum_{S \subseteq U}f_Sx^S \]

这里的 \(x^{S}\) 完全是形式记号,这个写法仿照了形式幂级数,但不应该看作一个关于 \(x\) 的函数。

运算

我们需要运算,首先和差加法逆是好定义的。

对于两个集合幂级数 \(f,g\),定义它们的和 \(f+g\)

\[(f+g)_S=f_S+g_S \]

对于集合幂级数 \(f\),定义加法逆 \(-f\)

\[(-f)_S=-f_S \]

对于集合幂级数 \(f,g\),定义减法 \(f-g\)

\[(f-g)_S=f_S-g_S \]

接下来考虑两个集合幂级数的乘法,也就是卷积。

我们知道,对于两数列 \(a,b\),其卷积 \(f\circ g=c\)

\[c_i=\sum_{x+y=i}a_xb_y \]

这里我们可以把 \(x+y=i\) 看成一个抽象的形式,即对于任意二元函数 \(\operatorname{op}(x,y)\),我们都可以定义

\[c_i=\sum_{\operatorname{op}(x,y)=i}a_xb_y \]

\(a,b\) 的某种卷积。

普通序列卷积中,这个运算是加法,对于集合我们尝试定义「加法」,我们考虑并。

这样就得到了集合并卷积,如果用二进制数表示集合,看起来就像是 OR 运算,所以也称 OR 卷积。

\[(f\ast g)_S=\sum_{L \cup R=S}f_Lg_R \]

求集合并卷积是简单的,定义 \(\operatorname{FMT}(f)_S=\sum_{T \subseteq S}f_T\),不难有

\[\operatorname{FMT}(f\ast g)_S=\sum_{L \cup R\subseteq S}f_Lg_R=\sum_{L,R \subseteq S}f_Lg_R=\operatorname{FMT}(f)_S\operatorname{FMT}(g)_S \]

对于多个的 OR 卷积,容易发现可以先全部 FMT,乘起来后再逆 FMT。

FMT 的求法是简单的,考虑高维前缀和。

对于逆 FMT,我们要用到子集反演:

\[f_S=\sum_{T \subseteq S}(-1)^{|S|-|T|}\operatorname{FMT}(f)_T=(-1)^{|S|}\sum_{T\subseteq S}(-1)^{|T|}\operatorname{FMT}(f)_T \]

证明:

\[\begin{aligned} &\sum_{T \subseteq S}(-1)^{|S|-|T|}\operatorname{FMT}(f)_T\\ =&\sum_{T\subseteq S}(-1)^{|S|-|T|}\sum_{T^{\prime}\subseteq T}f_{T^{\prime}}\\ =&\sum_{T^{\prime}\subseteq S}f_{T^{\prime}}\sum_{T^{\prime}\subseteq T \subseteq S}(-1)^{|S|-|T|}\\ =&\sum_{T^{\prime}\subseteq S}f_{T^{\prime}}\sum_{i=0}^{|S|-|T^{\prime}|}(-1)^{|S|-|T^{\prime}|-i}\binom{|S|-|T^{\prime}|}{i}\\ =&\sum_{T^{\prime}\subseteq S}f_{T^{\prime}}(-1)^{|S|-|T^{\prime}|}[|S|=|T^{\prime}|]\\ =&f_S \end{aligned} \]

子集卷积

接下来是重要的子集卷积,我们定义

\[(f\times g)_S=\sum_{L \sqcup R=S}f_Lg_R=\sum_{T \subseteq S}f_Tg_{S\setminus T} \]

这里 \(\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)\),定义复合

\[h(f)=\sum_{i \ge 0}h_if^i \]

是一个集合幂级数。

我们注意到两个性质(记 \(f^{\prime}\) 表示之前我们替换后的结果)

\[(f+g)^{\prime}=f^{\prime}+g^{\prime} \]

\[(f\times g)^{\prime}=f^{\prime}\ast g^{\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(x)=\sum_{i \ge 0}\dfrac{x^i}{i!}=1+x+\dfrac{x^2}{2}+\dfrac{x^3}{6}+\dots \]

\[\ln(1+x)=\sum_{n \ge 1}\dfrac{(-1)^{n+1}x^n}{n}=x-\dfrac{1}{2}x^2+\dfrac{1}{3}x^3-\dots \]

\[\dfrac{1}{1-x}=\sum_{n \ge 0}x^n \]

如何 exp,ln,求逆

求逆

给你 \(A\),要求

\[\sum_{i=0}^{n}A_iB_{n-i}=[n=0] \]

于是

\[A_0B_n=-\sum_{i=1}^{n}A_iB_{n-i} \]

\[B_n=-\dfrac{1}{A_0}\sum_{i=1}^{n}A_iB_{n-i} \]

\[B_0=\dfrac{1}{A_0} \]

ln

\(B(x)=\ln A(x)\),于是 \(B^{\prime}(x)=\dfrac{A^{\prime}(x)}{A(x)}\),可以直接求逆再积分。

但这样子常数太大,我们可以直接递推

\[B^{\prime}(x)A(x)=A^{\prime}(x) \]

\[(n+1)A_{n+1}=\sum_{i=0}^{n}(i+1)B_{i+1}A_{n-i}=(n+1)B_{n+1}+\sum_{i=0}^{n-1}(i+1)B_{i+1}A_{n-i} \]

\[B_{n+1}=\dfrac{(n+1)A_{n+1}-\sum_{i=1}^{n}iB_iA_{n+1-i}}{n+1} \]

\[B_{n}=A_n-\dfrac{\sum_{i=1}^{n-1}iB_iA_{n-i}}{n} \]

\[B_0=0 \]

exp

\(B(x)=\exp(A(X))\),于是 \(B^{\prime}(x)=A^{\prime}(x)B(x)\)

\[(n+1)B_{n+1}=\sum_{i=0}^{n}(i+1)A_{i+1}B_{n-i} \]

\[B_n=\dfrac{1}{n}\sum_{i=1}^{n}iA_{i}B_{n-i} \]

\[B_0=1 \]

部分 exp

我们定义 \(\exp_k(x)=\sum_{i=0}^{k}\dfrac{x^i}{i!}\)

\[B(x)=\sum_{i=0}^{k}\dfrac{A(x)^i}{i!} \]

\[B^{\prime}(x)=\sum_{i=0}^k \dfrac{A^{\prime}(x)A(x)^{i-1}}{(i-1)!} \]

\[B^{\prime}(x)=A^{\prime}(x)(B(x)-\dfrac{A(x)^k}{k!}) \]

\(C(x)=\dfrac{A(x)^k}{k!}\)(不难直接求得)

\[(n+1)B_{n+1}=\sum_{i=0}^{n}(i+1)A_{i+1}(B_{n-i}-C_{n-i}) \]

\[B_{n}=\dfrac{1}{n}\sum_{i=1}^{n}iA_{i}(B_{n-i}-C_{n-i}) \]

\[B_0=1 \]

其中 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)\),求连通生成子图数量。

做法

似乎并不好直接刻画连通性,但我们知道

\[\text{图}=\sum\text{连通块} \]

假设我们已经知道了对于点集 \(S\) 内部的连通生成子图数,令 \(g\) 表示 \(S\) 内部生成子图数,有

\[g=\exp f \]

反过来就有 \(f=\ln g\),而 \(g_S=2^{e(S)}\),直接做集合幂级数 ln 即可。

这里有一个启示,对于生成子图,我们一般考虑将其组合得到简单的,再反过来推导。

数连通二分生成子图 at_arc205_f

给你一个图 \(G=(V,E)\),求有多少个连通的生成子图是二分图。

解法

注意到

\[\text{二分图且染色}=\sum \text{连通二分图且染色} \]

染色是为了保证只计数一次。

\(g_S\) 表示 \(S\) 以内二分生成子图且染色的方案数,\(f_S\) 表示 \(S\) 以内连通二分生成子图且染色的方案数,所求即 \(\sum_{S \subseteq U}\dfrac{f_S}{2}\)

\[g=\exp f \]

\[f=\ln g \]

考虑如何求 \(g\)

\[g_S=\sum_{T \subseteq S}2^{e(T,S\setminus T)}=\sum_{T \subseteq S}2^{e(S)-e(T)-e(S\setminus T)}=2^{e(S)}\sum_{T \subseteq S}2^{-e(T)}2^{-e(S\setminus T)} \]

直接子集卷积。

数 DAG 定向(CF1193A 略改)

给你一个无向图 \(G=(V,E)\),你需要对每条边定向,使得定向后图为 DAG。

做法

\(f_S\) 表示将 \(S\) 的导出子图内所有边定向且为 DAG 的方案数。

考虑枚举出度为 \(0\) 的点集 \(T\),首先 \(T\) 要为独立集,然后所有从 \(S\setminus T\)\(T\) 的边的方向被唯一确定,似乎有

\[f_S=[S=\varnothing]+\sum_{T \subseteq S}[T\text{ 是独立集且非空}]f_{S\setminus T} \]

但这显然是错的,因为我们会重复计数,对于恰有 \(|T|\) 个点为出度为 \(0\) 点的情况下,会被重复计数 \(2^|S|-1\) 次。

考虑容斥,我们添加上容斥系数 \((-1)^{|T|-1}\),容易证明恰被计数一次。

这样朴素做是 \(\Theta(3^n)\) 的,无法通过。

这个转移是半在线的,后面会讲如何做半在线子集卷积,但这里可以直接推式子。

我们记 \(g_S=[S\text{ 是独立集且非空}](-1)^{|S|-1}\) 那么有

\[f=1+f\times g \]

于是有 \(f=\dfrac{1}{1-g}\),直接求逆即可。

数强连通生成子图 CTT2014 D1T2 主旋律

给你一个有向图,求有多少个生成子图强连通。

做法

考虑一个想法,用 \(2^m\) 减去所有有两个强连通分量的子图。

那么假设已经知道好了强连通分量的划分,那么内部就是强连通子图,外部就是 DAG 子图计数。

\(\mathrm{ans}_S\)\(S\) 为点集的生成子图个数,\(\mathrm{cof}_S\) 为将 \(S\) 划分为若干无出度强连通分量的所有方案的带权求和,权重为 \((-1)^{\mathrm{sz}-1}\)\(\mathrm{sz}\) 为划分出的强连通分量数。

根据之前的容斥,我们有

\[\mathrm{cof}_S=2^{e(S)}-\sum_{\varnothing \subsetneq T \subsetneq S} \]

数点双连通生成子图

给你一个无向图 \(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\)

那么对于这样一个划分,贡献为

\[(p_{u-1})_{P_1}\sum_{i=2}^{k}(p_{u-1})_{P_i}e(\{u\},P_i) \]

半在线卷积

有的时候我们并不能直接求逆解决,这时我们需要半在线。

例题 P4221 州区划分

\(n\) 座城市,每座城市有 \(w_i\) 人口,你要有序划分成若干州 \(\{V_1,\dots,V_k\}\),每个州非空且导出子图不是欧拉图,定义一个州的满意度为

\[\left(\dfrac{\sum_{u \in V_i}w_u}{\sum_{j=1}^{i}\sum_{u \in v_j}w_u}\right)^p \]

定义一个划分方案的权值为所有州满意度的乘积。

求所有划分方案的权值和。

解法

首先欧拉图的限制是无关紧要的,直接判就可以了。

直接令 \(W_S=(\sum_{u \in S}w_u)^p\),有转移

\[f_S=\dfrac{1}{W_S}\sum_{T \subseteq S}[T\text{ 非空且不是欧拉图}]W_Tf_{S\setminus T} \]

这里很烦的是带了一个 \(\dfrac{1}{W_S}\) 导致不能直接写成集合幂级数的形式。

回顾一下怎么求子集卷积的,每个 \(S\) 上维护了一个多项式,注意到子集卷积时每项次数只会变大。

于是我们枚举次数 \(0\dots n\),每次跑一个 OR 卷积就可以了。

posted @ 2025-10-22 10:21  ThisIsLu  阅读(12)  评论(0)    收藏  举报