生成函数
前言
基础部分:多项式的高级运算
多项式与形式幂级数
多项式
多项式的定义见小学课本。
多项式的相关内容见 多项式的高级运算
形式幂级数
去除多项式“只有有限项”的限制。
\(x\) 通常只是一个“形式”,不关心实际数值,“不用考虑与幂级数敛散性有关的问题”(不是很懂),相当于用一个 \(x\) 的多项式挂起来一个数列。
组合计数问题
组合对象
满足某一性质(比如联通)的树、图、串等组成的集合。集合内每个元素都定义了“大小”,我们通常把“大小”作为下边,用 \(A_n\) 来表示大小为 \(n\) 的元素的数量。
普通生成函数(OGF)
序列 \(\{ a_0,a_1,a_2,...,a_i\}\) 的 OGF 为:
也是比较常见的生成函数。常用于无标号的问题中。
常见数列的OGF(见《具体数学》)
指数生成函数(EGF)
序列 \(\{ a_i\}\) 的 EGF 为:
EGF 善于处理有标号计数问题,能够解决运算时的“分配标号”问题。
常见数列的EGF(见珍珠):
概率生成函数(PGF)
2018集训队论文 《浅谈生成函数在掷骰子问题上的应用》(杨懋龙)
一类比较特殊的生成函数,用于解决概率期望等问题。
概率生成函数是对一个随机变量定义的。\([x^n]F(x)\) 表示随机变量 \(X = n\) 的概率。
于是:
其中 \(DX\) 为方差,定义式为:\(\sum_i P(X=i)(i-\overline{X})\)
歌唱王国
设 \(f_n\) 表示恰好 \(n\) 次后结束的概率,\(g_n\) 为 \(n\) 次没结束的概率,\(F,G\) 为其生成函数,那么我们求的就是 \(F'(1)\)。设\(c\) 为字符集大小,\(m\) 为串长。有关系式:
第一个式子为 \(f,g\) 间的关系。第二个式子意义为添 \(m\) 个字符保证结束的两种表示。其中 \(a_i = [S[1...i]=S[m-i+1...m]]\)
那么有:
转而求 \(G(1)\)。搞第二个式子:
直接算即可。
还有个类似的题目:硬币游戏
集合计数
有标号集合计数
因为有标号,我们应该使用EGF。但是,当我们打算算出由 \(k\) 个 \(A(x)\)“拼接”而成的那个生成函数,就不能简单地 \(A^k(x)\) 了,因为我们不希望选择有顺序,因此答案是 \(\dfrac{A^k(x)}{k!}\)。
有意思的是,如果我们想要算出由任意个 \(A(x)\)“拼接”而成的那个生成函数,它是:
即对 \(A(x)\) 做exp。
注意,这里除 \(i!\) 并不与处理标号时用的 \(n!\) 冲突。
到底为什么要除 \(n!\) 呢?这和 有标号 有关系吗?实际上是没关系的,除 \(n!\) 主要还是因为生成函数的乘法乘出来的东西是有序的多元组。就比如果三个多项式相乘,乘出来的结果可以看作一个个三元组\((A,B,C)\),表示从第一个多项式中揪出来一个元素 \(A\),从第二个多项式中揪出来一个元素 \(B\),从第三个多项式中揪出来一个元素 \(C\),组成的三元组。其中\(A + B + C = n\) 的三元组数量记为 \(f_n\),作为最终的三元组序列的第 \(n\) 个元素。即我们乘完以后的结果是一堆形如 \((A, B, C)\) 的三元组。
然而我们真的要这样的结果吗?我们其实只要包含 \(ABC\) 三个元素即可,并不关心它是 \((A,B,C)\) 还是 \((B,C,A)\),即我们会在 \((A,B,C),(B,C,A)\) 等排列中都把方案算一遍(都是有编号的),而我们只需要一个,那么就除个 \(n!\) 即可。
至于 \(ABB\) 这样的三元素是否一定会被算 \(n!\) 遍,即有序变无序为什么能直接除 \(n!\),我也感觉很疑惑,可能是我小学没学好吧。(不懂不懂不懂不懂)
背包计数
有若干种物品,每种物品有无限件,体积为 \(i\) 的物品有 \(a_i\) 种。问装满 \(j\) 体积的背包的方案数。
直接搞出每种物品的OGF为 \(\{1,0,0,...,1,0,0,...\} : \dfrac{1}{1-x^i}\),然后直接卷积即为答案。
正确性:刚才不是还要除 \(i!\),现在怎么不除了?因为我们这里可以把 \((A,B,C)\) 看作第一个物品为 \(A\),第二个物品为 \(B\),第三个物品为 \(C\),这恰好符合我们的意图。即我们把集合问题转化成了序列问题。
现在我们继续化简式子:
对于 \(exp\) 里面的那个式子,对于每个 \(j\) 暴力算出所有小于等于 \(n\) 次的项的贡献即可。复杂度 \(O(nlnn)\)。最后再 \(exp\) 一下就好。总复杂度为 \(O(nlogn)\)。
其中第三行推到第四行需要一个式子:
这个式子比较重要,建议背过。下面不加说明地(并且不规范地)给出两种证明:
证明一:
证明二:
练习:01背包计数:
例题:P4389 付公主的背包
环的计数
有标号环计数
与有标号集合计数类似,\(n\) 个环拼接的结果是 \(n\) 元组而不是环,最后要除 \(n\),因为同一种方案我们算了 \(n\) 次。
由 \(n\) 种大小不同的元素各取任意多个组成环的EGF是:
例题:基环树计数
\(n\) 个点的基环树有多少?点有编号,无重边自环。
首先要知道一个常识:由 \(n\) 个点(有编号)组成的有根树数量为 \(n^{n-1}\) 个, 无根树为 \(n^{n-2}\) 个。
有根树EGF为:
基环树可以看作由大于等于 3 棵有根树组成的环,并且可以翻转。因此答案为:
项链计数
现有 \(n\) 种重量不同的珠子,第 \(i\) 种珠子的重量为 \(i\),有 \(a_i\) 种颜色。问串成的总重为 \(k\) 的项链的方案数。项链可旋转,不可翻转。
现在我们也不知道多算了几倍,不好直接除一个数作为答案。
项链?旋转?Polya定理!
众所周知,\(n\) 个珠子,\(c\) 种颜色的本质不同项链数为:
不过现在 \(c\) 由重量决定,与 \(x^i\) 前的系数有关。那么 \(n\) 个珠子组成的项链的OGF为:
其中 \(n/g\) 是“环”的大小,\(A(x^{n/g})\) 表示将 \(A(x)\) 的所有元素重量翻了 \(n/g\) 倍的 OGF(毕竟我们要求一个“环”的颜色都相同,可以看作一个重量为原来的 \(n/g\) 倍的元素)
注意,这是个 OGF,第 \(i\) 项系数表示总重为 \(i\) 的 \(n\) 个珠子的方案数。(这里不懂,为什么 \(g\) 次方以后不用除阶乘,这不是集合吗?好像真不是...Polya定理里面的这些“环”可以看作“序列”,应该是有顺序的)
好,我们继续推式子:
这是 \(n\) 个珠子的 OGF。但是我们不限制珠子数,那么我们把所有的 \(n\) 的 OGF 加起来就好了。
同样,\(A(x^d)\) 的有用的项并不多,因此算出 \(ln(1-A(x))\) 后依次代入 \(x^d\),暴力求和即可。
复杂度:\(O(nlogn)\)
参考文献
-
国家集训队2015年论文《生成函数的运算与组合计数问题》
-
《具体数学》