参考自 x义x 的同名博客。
一、无标号计数
-
定义 1.1(组合类):组合类是一个集合 A 和一个附带的大小函数 f:A→N(记 f(a) 为 |a| 或 |a|A)。
它需要满足对于任意 n∈N,An:={a∈A:|a|=n} 都是有限集(从而 A 是至多可数集)。
组合类中的元素被称作组合对象。
定义 A 的计数序列为 (An)∞n=0 满足 An:=cardAn。
-
定义 1.2(计数序列的 OGF):设组合类 A 的计数序列为 (An)∞n=0。定义 (An)∞n=0 的 OGF 为形式幂级数:
A(z):=∑n∈NAnzn
容易看出,上述定义和下面是等价的:
A(z):=∑a∈Az|a|
-
定义 1.3(笛卡尔积):设 B,C 是组合类。定义它们的笛卡尔积 B×C 的大小函数满足对于任意 (b,c)∈B×C 有 |(b,c)|B×C:=|b|B+|c|C。
-
引理 1.4:设 B,C 是组合类,A=B×C。那么 A(z)=B(z)C(z)。
笛卡尔积的组合意义是:将两个组合类中的组合对象有序地拼在一起。
- 定义 1.5(不交并):设 B,C 是组合类且 B∩C=∅。定义它们的无交并 B∪C 的大小函数满足对于任意 a∈B∪C 有 |a|B∪C:={|a|Ba∈B|a|Ca∈C。
- 定义 1.6(和):设 B,C 是组合类。定义它们的和为 B+C:=(E1×B)∪(E2×C),其中 E1,E2 是两个不同的、仅包含一个大小为 0 的组合对象的组合类。
- 引理 1.7:设 B,C 是组合类且 B∩C=∅,A=B∪C。那么 A(z)=B(z)+C(z)。
- 引理 1.8:设 B,C 是组合类,A=B+C。那么 A(z)=B(z)+C(z)。
和的组合意义是:区分所属组合类地将两个组合类合并。
- 定义 1.9(有序列表构造):设 B 是组合类且 [z0]B(z)=0。定义它的有序列表构造为 SEQ(B):=⋃l∈NBl。
- 引理 1.10:设 B 是组合类且 [z0]B(z)=0,A=SEQ(B)。那么 A(z)=11−B(z)。
有序列表构造的组合意义是:用同一组合类内的若干组合对象有序地拼在一起。
-
定义 1.11(映射群):映射群是由映射构成的集合、且在复合运算下构成群。
-
定义 1.12(等价类):设 B 是组合类,(Gn)∞n=0 是映射群列,满足 Gn 中的元素是定义域和对应域都是 {b∈B:|b|=n} 的映射。
称 b1,b2∈B 本质相同(记为 b1≡b2),当且仅当 |b1|=|b2| 且存在 g∈G|b1| 使得 g(b1)=b2。
容易证明本质相同关系是自反、对称、传递的。
定义组合类 B/G:={{b2∈B:b1≡b2}:b1∈B},即所有等价类构成的集合。
对于 S∈B/G 定义 |S|B/G 为 S 中任一组合对象的大小,注意与 |S| 区分。
-
定义 1.13(环构造):设 B 是组合类且 [z0]B(z)=0。定义它的环构造为 CYC(B)=(SEQ(B)∖{()})/G。其中 Gn 是所有 n 元组上的循环位移构成的群。
-
引理 1.14:设 B 是组合类且 [z0]B(z)=0,A=CYC(B)。那么:
A(z)=∑k≥1φ(k)kln11−B(zk)
其中 φ 是数论上的欧拉函数。
证明:考虑使用 Burnside 引理。先枚举序列长度 n,再枚举循环位移的步数 d,可得:
A(z)=∑n≥11nn∑d=1B(zn/gcd(d,n))gcd(d,n)
其中 B(zs) 相当于把同一个组合对象复制为 s 份。转为枚举 k=n/gcd(d,n) 和 g=gcd(d,n):
A(z)=∑k≥1∑g≥1B(zk)g1kgkg∑d=1[gcd(d,kg)=g]=∑k≥1φ(k)k∑g≥1B(zk)gg=∑k≥1φ(k)k(∫11−x)∣∣∣x=B(zk)=∑k≥1φ(k)k(ln11−x)∣∣∣x=B(zk)
环构造的组合意义是:用同一组合类内的若干组合对象拼成一个环。
-
定义 1.15(可重集构造):设 B 是组合类且 [z0]B(z)=0。定义它的可重集构造为 MSET(B)=SEQ(B)/G,其中 Gn 是所有 n 元置换。
-
引理 1.16:设 B 是组合类且 [z0]B(z)=0,A=MSET(B)。那么:
A(z)=∏i≥1(11−xi)Bi
证明:相当于将 B 中的每个组合对象先做一次 SEQ,再笛卡尔积组合起来。
-
引理 1.17:设 B 是组合类且 [z0]B(z)=0,A=MSET(B)。那么:
A(z)=exp(∑i≥1B(zi)i)
证明:代数上,可以将引理 16 中的式子先取 ln 再取 exp 得到。
组合意义上,仍然考虑 Burnside 引理。先枚举序列长度 n,再枚举置换 g,设 g 环分解得到 (ai)mi=1,那么:
A(z)=∑n≥11n!∑gm∏i=1B(zai)
其实就是很经典的用环刻画排列,这里略去具体过程,最后即可得到原式。
可重集构造的组合意义是:用同一组合类内的若干组合对象拼在一起,只关注每种组合对象的出现次数(无序)。
-
例 1.18:设 T 是所有无标号有根树构成的组合类,那么应当有:
T=Z×MSET(T)
其中 Z 是仅包含一个大小为 1 的组合对象的组合类。它在这里的意义是树的根。
-
定义 1.19(染色):设有限集 M={1,⋯,m} 和作用在 M 上的置换群 G。设 B 是组合类。M→B 的映射被称为染色。
称两个染色 ϕ1,ϕ2∈BM 本质相同,当且仅当存在 g∈G 使得 ϕ1∘g=ϕ2。类似定义等价类集合 BM/G。
设 B 还附带一个权重函数 w。那么定义一个染色 ϕ∈BM 的权重为 w(ϕ)=∏n∈Mw(ϕ(n))。
显然同一个等价类中的染色的权重都是相同的,将其定义为该等价类的权重。
-
引理 1.20(Polya 定理):设有限集 M={1,⋯,m} 和作用在 M 上的置换群 G。设 B 是组合类,附带权重函数 w。那么:
∑ϕ∈BM/Gw(ϕ)=Z(G;∑b∈Bw(b),⋯,∑b∈Bwm(b))Z(G;x1,⋯,xm)=1|G|∑g∈Gxj1(g)1⋯xjm(g)m
其中 ji(g) 表示 g 的环分解中中大小为 i 的环的个数。
证明:咕。
-
例 1.21:取 w(b):=1,得到:
|BM/G|=1|G|∑g∈G|B|c(g)
其中 c(g)=∑j(g) 表示环分解中环的个数。
其含义是计算本质不同染色方案的数量。
-
例 1.22:取 w(b):=z|b|,得到:
∑ϕ∈BM/Gw(ϕ)=Z(G;B(z),⋯,B(zm))
其含义是计算每种本质的染色方案的颜色大小之和的生成函数。
-
例 1.23:取 Gm 为所有 m 元置换,得到:
∑m≥0∑ϕ∈B{1,⋯,m}/Gmw(ϕ)=exp(∑i≥11i∑b∈Bwi(b))
其含义是在 B 中无序地选若干个可以重复的物品,这些物品的大小和的生成函数。
二、有标号计数
-
定义 2.1(有标号的组合对象):称一个组合对象(这里为了直观默认为图)是弱标号的,当且仅当它的每一个节点都附带一个互不相同的正整数标号。
你可以理解为,这个组合对象附带了一个函数 f,其中 fi 表示第 i 个节点的标号(注意这里我们并没有具体定义第 i 个节点是什么,但目的只是将所有节点区分开来)。
称一个大小为 n 的组合对象是(强)标号的,当且仅当它是弱标号的,且所有节点的标号恰好构成 1,⋯,n 的一个排列。
首先要注意的是,将一个大小为 n 的无标号的组合对象附上标号,所得到的有标号的组合对象的数量并不一定是 n!。比如对一棵 “两点一边” 的无标号树标号后只能形成一种有标号树。
-
定义 2.2(离散化):定义弱标号组合对象 a 的离散化为强标号组合对象 ρ(a),使得所有节点的标号大小关系仍然不变。
-
定义 2.3(计数序列的 EGF):设组合类 A 的计数序列为 (An)∞n=0。定义 (An)∞n=0 的 EGF 为形式幂级数:
A(z):=∑n∈NAnznn!
容易看出,上述定义和下面是等价的:
A(z):=∑a∈Az|a||a|!
本章我们仅讨论由有标号的组合对象形成的组合类,所讨论的生成函数均为 EGF。
-
定义 2.4(标号积):设 B,C 是组合类,b∈B,c∈C。
定义 b,c 的标号积为组合类 b⋆c:={(b′,c′):(b′,c′)是强标号的,ρ(b′)=b,ρ(c′)=c},其大小函数定义为 |(b′,c′)|:=|b|+|c|。
定义 B,C 的标号积为组合类 B⋆C:=⋃b∈B,c∈Cb⋆c。
-
引理 2.5:设 B,C 是组合类,A=B⋆C。那么 A(z)=B(z)C(z)。
标号积的组合意义是:将两个组合类中的组合对象有序地拼在一起,并重新分配标号、使得维持在原组合类中的标号大小关系。
- 定义 2.6(有序列表构造):设 B 是组合类且 [z0]B(z)=0。定义它的有序列表构造为 SEQ⋆(B):=⋃l∈NBl。这里 B 的幂以 ⋆ 为基础定义。
- 引理 2.7:设 B 是组合类且 [z0]B(z)=0,A=SEQ⋆(B)。那么 A(z)=11−B(z)。
有序列表构造的组合意义是:用同一组合类内的若干组合对象有序地拼在一起,并重新分配标号、使得维持在原组合类中的标号大小关系。
-
定义 2.8(集合构造):设 B 是组合类且 [z0]B(z)=0。定义它的集合构造为 SET(B)=SEQ⋆(B)/G,其中 Gn 是所有 n 元置换。
-
引理 2.9:设 B 是组合类且 [z0]B(z)=0,A=SET(B)。那么 A(z)=expB(z)。
证明:枚举 b∈B 出现了 i 次,但由于这 i 个 b 应当是不加区分的,而给它们标号时会重复计算 i! 次,所以要除掉:
A(z)=∏b∈B∑i≥0(z|b||b|!)ii!=∏b∈Bexp(z|b||b|!)=exp(∑b∈Bz|b||b|!)=expB(z)
或者另一种组合意义的解释:考虑一个带标号的 n 元组,由于已经带上标号了,所以它们之间是两两相互区分的,那么这种重标号的 “set” 肯定会被恰好计算 n! 次,所以应当有:
A(z)=∑n≥0B(z)nn!=expB(z)
集合构造的组合意义是:用同一组合类内的若干组合对象拼在一起,并重新分配标号、使得维持在原组合类中的标号大小关系,同种重标号的 “set” 仅会被算一次。
-
定义 2.10(选根):设 B 是组合类。定义它的选根为 PT(B):=⋃n≥0Bn×Z1..n。其中 Z1..n 的大小函数满足 |i|Z1..n=0。
-
引理 2.11:设 B 是组合类,A=PT(B)。那么 A(z)=B′(z)z。
证明:A(z)=∑i≥1iBizi=B′(z)z。
选根的组合意义是:在组合对象中选择一个特殊节点。
-
定义 2.12(复合):设 B,C 是组合类。定义它们的复合为 B∘C=∑n≥00(Bk)×SETk(C)。其中 0(Bk) 为将 Bk 的大小函数设置为恒等于 0 后的结果。
-
引理 2.13:设 B,C 是组合类,A=B∘C。那么 A(z)=(B∘C)(z)。
证明:(B∘C)(z)=∑n≥0BnC(z)nn!,其中 C(z)nn! 的组合意义是选出一个包含恰好 n 个 C 中组合对象并重标号的 “set”,然后由于 “set” 中的元素是两两区分的,那么直接把它们当成标号即可。
复合一般要求 B 中的组合对象的标号不能有大小关系的限制,否则其组合意义不好解释。它的结构一般有明显的分层。可以通过下面这几个例子来理解:
-
例 2.14:记 C 为所有有标号序列形成的组合类,那么 C(z)=∑n≥0n!n!zn=11−z。
于是 A=SEQ⋆(B)=C∘B,且 A(z)=11−B(z)=C(B(z))。
-
例 2.15:记 C 为所有有标号环形成的组合类,那么 C(z)=∑n≥1(n−1)!n!zn=∑n≥1znn。
于是 A=CYC⋆(B)=C∘B,且 A(z)=∑n≥1B(z)nn。
-
例 2.16:记 C 为所有有标号无序集合形成的组合类(注意,由于是无序集合,所以这里的标号仅是为了区分它们,所以仅有一种标号方式),那么 C(z)=∑n≥11n!zn=ez。
于是 A=SET(B)=C∘B,且 A(z)=expB(z)。
三、集合幂级数
咕。
例题
【ZJOI2018】树
题意:
随机生成 k 棵大小为 n 的有标号有根树,其中标号要求父亲比儿子小,求这 k 棵树同构的概率。
n≤2000,k≤109。
题解:
一开始的想法是用有标号计数来做,但其实你发现由于它是要对每个无标号有根树 b 求标号方案 w(b) 的 k 次方之和,所以还不太一样,这里我们按照题意考虑构造一种生成函数。
注意 w(b) 并不是拓扑序的数量,因为点本来是不区分的,比如 “一个根两个儿子” 这棵三个点树只有一种标号方案而非两种。
首先考虑对两棵无标号有根树 b1,b2 分配标号方案,方案数为 w(b1,b2)=(|b1|+|b2||b1|)w(b1)w(b2),那么 (w(b1,b2)(|b1|+|b2|)!)k=(w(b1)|b1|!)k(w(b2)|b2|!)k,于是考虑构造生成函数:
B(z)=∑b∈B(w(b)|b|!)kz|b|
记 f(b)=(w(b)|b|!)k,它就是一个组合对象的 “权”。那么 B(z)=∑b∈Bf(b)z|b|。
现在考虑分析一棵树的构造。
定义 A=SUBT(B) 为将 B 中的若干棵无根树拼成另一个点的所有子树。这其实和有标号中的集合构造很像,但有个 k 次幂:
A(z)=∏b∈B∑i≥0(f(b)z|b|)ii!k
定义 RT(A) 为将 A 中拼出来的若干棵子树加上根。显然 B 就是 RT(A)。那么应当有:
B(z)=∑n≥0n!k(n+1)!kAnzn+1
我们需要对 A(z) 做进一步的化简,使得它与 B(z) 关联上:
A(z)=∏b∈B∑i≥0(f(b)z|b|)ii!k=exp∑b∈Bln∑i≥0(f(b)z|b|)ii!k
记 ln∑i≥0xii!k=∑j≥1gjxj,那么:
A(z)=exp∑b∈B∑j≥0gj(f(b)z|b|)j=exp∑j≥0gj∑b∈B(f(b)z|b|)j
这一步看起来就推不下去了。
但实际上,发现如果我们要推导 ∑b∈B(f(b)z|b|)j 的话,其实和刚刚 B(z) 的推导是类似的,因为 f(b) 本来就是 w(b)|b|! 的幂的形式。结合另一个可以预见到的原因(在这串式子下面有讲),正解是将 k 也当成了变量放到了角标下,然后:
Ak(z)=exp∑j≥1gk,j∑b∈B(fk(b)z|b|)j=exp∑j≥1gk,j∑b∈B(wk(b)|b|!kz|b|)j=exp∑j≥1gk,j∑b∈Bwjk(b)|b|!jkzj|b|=exp∑j≥1gk,jBjk(zj)
显然 Bjk(z) 只需要 nj 项,而且 Ajk(z) 递归下去的 Bj′jk(z) 也仍然只需要 nj′j 项。所以需要计算的 j 是有限的。具体来说:
- [zm]Bjk(z) 依赖于 [zm−1]Ajk(z),对所有 m 总计算耗时 O(nj)。
- [zm]∑j′≥1gjk,j′Bj′jk(zj′) 依赖于所有 j′|m 的 [zm/j′]Bj′jk(z),对所有 m 总计算耗时 O(njlognj)。
- 计算 Ajk(z)=exp∑j′≥1gjk,j′Bj′jk(zj′) 使用暴力递推式 exp,总计算耗时 O((nj)2)。
总时间复杂度 O(∑nj=1(nj)2)=O(n2)。
【ABC230H】Bullion
题意:
有 n 种物品,第 i 种重量为 wi。
一个非空的袋子,可以装若干个物品(每种物品可以装任意多个)和若干个非空的袋子,但不能啥也不装。其重量为装的东西的总重加一。
对 i=1,⋯,W 求非空袋子总重为 i 的方案数。
n,W≤2×105。
题解:
组合类分析后,容易得到下式:
B(z)=z(exp(∑i≥1B(zi)i)n∏i=111−zwi−1)
我们要求 B(z) 的前 n 项系数。
我们先解决另一个问题:已知 Cn=∑ni=0AiBn−i,而 Cn 可以推出 An+1,Bn+1,求 C0,⋯,n−1。
该问题被称为全在线卷积,处理方法是倍增。假设我们已经知道了 A,B,C 前 n 项系数,现在想求它们前 2n 项系数。我们先直接卷积得到 A0,⋯,n−1×B0,⋯,n−1 对 Cn,⋯,2n−1 的贡献,然后剩下要算的只有 A0,⋯,n−1×Bn,⋯2n−1 和 B0,n−1×An,2n−1 的贡献。于是转化为两个半在线的问题,可以用分治 NTT O(nlog2n) 解决。总时间复杂度 O(nlog2n+n2log2n2+⋯)=O(nlog2n)。
然后上面那个问题也是类似处理。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下