【学习笔记】生成函数入门
1.1 1.1 1.1 普通生成函数 O G F OGF OGF: F ( x ) = ∑ n = 0 ∞ f n x n F(x)=\sum_{n=0}^{\infty}f_nx^n F(x)=∑n=0∞fnxn
定义 S E Q A SEQ_A SEQA是 A A A中元素排成的序列组成的集合,一个序列的大小定义为各元素大小之和,那么 S E Q A SEQ_A SEQA的 O G F OGF OGF:
S E Q A ( x ) = 1 + A ( x ) + A 2 ( x ) + . . . + A n ( x ) = 1 1 − A ( x ) SEQ_A(x)=1+A(x)+A^2(x)+...+A^n(x)=\frac{1}{1-A(x)} SEQA(x)=1+A(x)+A2(x)+...+An(x)=1−A(x)1 。
1.2 1.2 1.2 背包计数问题:有 k k k种物品,每种物品有容量 v i v_i vi和数量 n i n_i ni,问组合出容量为 V V V的方案数。
F ( x ) = ∏ i = 1 k ( 1 + x v i + x 2 v i + . . . + x n i v i ) = ∏ i = 1 n x ( n i + 1 ) v i − 1 x v i − 1 F(x)=\prod_{i=1}^k(1+x^{v_i}+x^{2v_i}+...+x^{n_iv_i})=\prod_{i=1}^n\frac{x^{(n_i+1)v_i}-1}{x^{v_i}-1} F(x)=∏i=1k(1+xvi+x2vi+...+xnivi)=∏i=1nxvi−1x(ni+1)vi−1
假设背包有无穷种物品,每种物品的体积为 i i i,个数也无限,把 n n n的正整数拆分的方案数记作 p ( n ) p(n) p(n), p p p也叫分拆数。
不难得到 p ( n ) p(n) p(n)的生成函数: F ( x ) = ∏ i = 1 ∞ 1 1 − x i F(x)=\prod_{i=1}^{\infty}\frac{1}{1-x^i} F(x)=∏i=1∞1−xi1
两边取对数,有 ln F ( x ) = − ∑ i = 1 ∞ ln ( 1 − x i ) \ln F(x)=-\sum_{i=1}^{\infty}\ln(1-x^i) lnF(x)=−∑i=1∞ln(1−xi)
在 m o d x n + 1 \bmod \ x^{n+1} mod xn+1意义下可以把无穷和变为有限的: ln F ( x ) = − ∑ i = 1 n ln ( 1 − x i ) \ln F(x)=-\sum_{i=1}^n\ln(1-x^i) lnF(x)=−∑i=1nln(1−xi)
求右边的麦克劳林展式:
ln F ( x ) = − ∑ i = 1 n ln ( 1 − x i ) = ∑ i = 1 n ∑ j = 1 ∞ x i j j = ∑ j = 1 ∞ 1 j ∑ i = 1 n x i j = ∑ j = 1 n 1 j ∑ i = 1 ⌊ n j ⌋ x i j \ln F(x)=-\sum_{i=1}^n\ln(1-x^i)=\sum_{i=1}^n\sum_{j=1}^{\infty}\frac{x^{ij}}{j}=\sum_{j=1}^\infty\frac{1}{j}\sum_{i=1}^nx^{ij}=\sum_{j=1}^n\frac{1}{j}\sum_{i=1}^{\lfloor\frac{n}{j}\rfloor}x^{ij} lnF(x)=−∑i=1nln(1−xi)=∑i=1n∑j=1∞jxij=∑j=1∞j1∑i=1nxij=∑j=1nj1∑i=1⌊jn⌋xij
右边和式可以处理出来,再对其求多项式 exp \exp exp即可,复杂度 O ( n log n ) O(n\log n) O(nlogn)。
1.3 1.3 1.3 指数生成函数 E G F EGF EGF: F ( x ) = ∑ n = 0 ∞ f n x n n ! F(x)=\sum_{n=0}^{\infty}f_n\frac{x^n}{n!} F(x)=∑n=0∞fnn!xn
一次积分相当于右移一项,一次求导相当于左移一项
∫ F ( x ) = ∑ n = 1 ∞ f n − 1 x n n ! \int F(x)=\sum_{n=1}^\infty f_{n-1}\frac{x^n}{n!} ∫F(x)=∑n=1∞fn−1n!xn, F ′ ( x ) = ∑ n = 0 ∞ f n + 1 x n n ! F'(x)=\sum_{n=0}^{\infty}f_{n+1}\frac{x^n}{n!} F′(x)=∑n=0∞fn+1n!xn
两个函数的卷积: h n = ∑ k = 0 n ( n k ) f k g n − k h_n=\sum_{k=0}^n\binom{n}{k}f_kg_{n-k} hn=∑k=0n(kn)fkgn−k,也把序列 h h h叫做序列 f f f和 g g g的二项卷积
1.4 1.4 1.4 组合意义: O G F OGF OGF考虑的是多重集的组合问题, E G F EGF EGF考虑的是多重集的排列问题。
1.5 1.5 1.5 有时我们需要考虑带标号的组合对象,如标号图。
定义 S E T A SET_A SETA是 A A A中元素任意拼接组成的集合(拼接时不考虑顺序), S E T A SET_A SETA的 E G F EGF EGF:
S E T A ( x ) = 1 + A ( x ) + A 2 ( x ) 2 + . . . + A n ( x ) n ! = exp ( A ( x ) ) SET_A(x)=1+A(x)+\frac{A^2(x)}{2}+...+\frac{A^n(x)}{n!}=\exp(A(x)) SETA(x)=1+A(x)+2A2(x)+...+n!An(x)=exp(A(x))
一个带标号的简单无向图是若干个联通分量不考虑顺序拼接成的, G G G是简单无向图的 E G F EGF EGF, C C C是简单连通图的 E G F EGF EGF,那么:
G ( x ) = ∑ n = 0 ∞ 2 ( n 2 ) x n n ! G(x)=\sum_{n=0}^{\infty}2^{\binom{n}{2}}\frac{x^n}{n!} G(x)=∑n=0∞2(2n)n!xn, exp ( C ( x ) ) = G ( x ) \exp(C(x))=G(x) exp(C(x))=G(x)
所以 C ( x ) = ln G ( x ) C(x)=\ln G(x) C(x)=lnG(x)
1.6 1.6 1.6 集合划分问题:集合 S S S的一个划分是把 S S S分成两两不相交的非空子集,并且它们的并是 S S S。
不难发现,划分的结果是由若干个子集无序拼接起来的。对于一个集合而言,不能选空集,而分出 1 , 2 , . . . , n 1,2,...,n 1,2,...,n个的方案数都只有一种,只有在拼接的时候指定编号。
故一个集合分出元素的 E G F EGF EGF是 exp ( x ) − 1 \exp(x)-1 exp(x)−1,集合的划分的 E G F EGF EGF是 exp ( exp ( x ) − 1 ) \exp(\exp(x)-1) exp(exp(x)−1)。
bell \text{bell} bell数 B n B_n Bn是基数为 n n n的集合划分数目,之前我们推导出了 B n B_n Bn的 E G F EGF EGF是 exp ( exp ( x ) − 1 ) \exp(\exp(x)-1) exp(exp(x)−1),可以快速求前 n n n个 bell \text{bell} bell数。
1.7 1.7 1.7 第二类 Stirling \text{Stirling} Stirling数: { n m } \begin{Bmatrix}n \\ m\end{Bmatrix} {nm}表示将 n n n个不同的元素划分称 m m m个集合的方案数。
我们可以写出第二类 Stirling \text{Stirling} Stirling数的 E G F EGF EGF,假设 m m m是一个定值,那么有
∑ n = 0 ∞ a n x n n ! = ( exp ( x ) − 1 ) m m ! \sum_{n=0}^{\infty}a_n\frac{x^n}{n!}=\frac{(\exp(x)-1)^m}{m!} ∑n=0∞ann!xn=m!(exp(x)−1)m, a n = { n m } a_n=\begin{Bmatrix}n \\ m\end{Bmatrix} an={nm}
不难求得 { n m } = 1 m ! ∑ k = 0 m ( − 1 ) m − k ( m k ) k n \begin{Bmatrix}n \\ m\end{Bmatrix}=\frac{1}{m!}\sum_{k=0}^m(-1)^{m-k}\binom{m}{k}k^n {nm}=m!1∑k=0m(−1)m−k(km)kn
把 m ! m! m!放到和式里面: { n m } = ∑ k = 0 m ( − 1 ) m − k ( m − k ) ! k n k ! \begin{Bmatrix}n \\ m\end{Bmatrix}=\sum_{k=0}^m\frac{(-1)^{m-k}}{(m-k)!}\frac{k^n}{k!} {nm}=∑k=0m(m−k)!(−1)m−kk!kn
这是一个卷积的形式,给定 n n n,可以快速算出 { n m } ( 1 ≤ m ≤ n ) \begin{Bmatrix}n \\ m\end{Bmatrix}(1\le m\le n) {nm}(1≤m≤n)
给定 m m m,用 ∑ n = 0 ∞ a n x n n ! = ( exp ( x ) − 1 ) m m ! \sum_{n=0}^{\infty}a_n\frac{x^n}{n!}=\frac{(\exp(x)-1)^m}{m!} ∑n=0∞ann!xn=m!(exp(x)−1)m, a n = { n m } a_n=\begin{Bmatrix}n \\ m\end{Bmatrix} an={nm}可以快速算出前 n n n个 { n m } \begin{Bmatrix}n \\ m\end{Bmatrix} {nm}
复杂度 O ( n log n ) O(n\log n) O(nlogn)。这就是第二类斯特林数行/列
1.8 1.8 1.8 第一类 Sirling \text{Sirling} Sirling数: [ n m ] \begin{bmatrix}n \\ m\end{bmatrix} [nm]表示将 n n n个不同元素划分为 k k k个互不区分的非空轮换的方案数。
递推式: [ n m ] = [ n − 1 m − 1 ] + ( n − 1 ) [ n − 1 m ] \begin{bmatrix}n \\ m\end{bmatrix}=\begin{bmatrix}n-1 \\ m-1\end{bmatrix}+(n-1)\begin{bmatrix}n-1 \\ m\end{bmatrix} [nm]=[n−1m−1]+(n−1)[n−1m]
1.8.1 1.8.1 1.8.1 同一行第一类斯特林数计算
我们构造同行第一类斯特林数的生成函数,即 F n ( x ) = ∑ i = 0 n [ n m ] x i F_n(x)=\sum_{i=0}^n\begin{bmatrix}n \\ m\end{bmatrix}x^i Fn(x)=∑i=0n[nm]xi
根据递推公式,不难写出: F n ( x ) = ( n − 1 ) F n − 1 ( x ) + x F n − 1 ( x ) F_n(x)=(n-1)F_{n-1}(x)+xF_{n-1}(x) Fn(x)=(n−1)Fn−1(x)+xFn−1(x)
于是 F n ( x ) = ∏ i = 0 n − 1 ( x + i ) F_n(x)=\prod_{i=0}^{n-1}(x+i) Fn(x)=∏i=0n−1(x+i)
这其实是 x x x的 n n n次上升阶乘幂,记作 x n ‾ x^{\overline n} xn。用上升幂相关做法可以 O ( n log n ) O(n\log n) O(nlogn)求出。
1.8.2 1.8.2 1.8.2 同一列第一类斯特林数的计算
显然,单个轮换的指数型生成函数为 F ( x ) = ∑ i = 1 n ( i − 1 ) ! x i i ! F(x)=\sum_{i=1}^n\frac{(i-1)!x^i}{i!} F(x)=∑i=1ni!(i−1)!xi
它的 k k k次幂就是 [ i k ] \begin{bmatrix}i \\ k\end{bmatrix} [ik]的指数型生成函数, O ( n log n ) O(n\log n) O(nlogn)计算即可。
1.9 1.9 1.9 上升幂的计算
考虑倍增, x 2 n ‾ = x n ‾ ( x + n ) n ‾ x^{\overline {2n}}=x^{\overline n}(x+n)^{\overline n} x2n=xn(x+n)n
于是现在我们有多项式 f ( x ) f(x) f(x),要求 f ( x + c ) f(x+c) f(x+c)的值
不难得到 f ( x + c ) f(x+c) f(x+c)可以二项式展开然后卷积求出。
复杂度 O ( n log n ) O(n\log n) O(nlogn) 。
用上升幂求第二类斯特林数的列:
利用递推式 { n m } = { n − 1 m − 1 } + m { n − 1 m } \begin{Bmatrix}n \\ m\end{Bmatrix}=\begin{Bmatrix}n-1 \\ m-1\end{Bmatrix}+m\begin{Bmatrix}n-1 \\ m\end{Bmatrix} {nm}={n−1m−1}+m{n−1m}
设 F k ( x ) = ∑ i = 0 ∞ { i k } x i F_k(x)=\sum_{i=0}^{\infty}\begin{Bmatrix}i \\ k\end{Bmatrix}x^i Fk(x)=∑i=0∞{ik}xi
不难发现 F k ( x ) = x F k − 1 ( x ) + k x F k ( x ) F_k(x)=xF_{k-1}(x)+kxF_k(x) Fk(x)=xFk−1(x)+kxFk(x),那么 F k ( x ) = x 1 − k x F k − 1 ( x ) F_k(x)=\frac{x}{1-kx}F_{k-1}(x) Fk(x)=1−kxxFk−1(x)
那么 F k ( x ) = ∏ i = 1 k x 1 − i x = x k ( ∏ i = 1 k ( 1 − i x ) ) − 1 F_k(x)=\prod_{i=1}^k\frac{x}{1-ix}=x^k(\prod_{i=1}^k(1-ix))^{-1} Fk(x)=∏i=1k1−ixx=xk(∏i=1k(1−ix))−1
考虑算 ∏ i = 1 k ( 1 − i x ) \prod_{i=1}^k(1-ix) ∏i=1k(1−ix)。
∏ i = 1 k ( 1 − i x ) = x k ∏ i = 1 k ( x − 1 − i ) \prod_{i=1}^k(1-ix)=x^k\prod_{i=1}^k(x^{-1}-i) ∏i=1k(1−ix)=xk∏i=1k(x−1−i)
注意到 ∏ i = 1 k ( x − i ) \prod_{i=1}^k(x-i) ∏i=1k(x−i)翻转后就能得到 x k ∏ i = 1 k ( x − 1 − i ) x^k\prod_{i=1}^k(x^{-1}-i) xk∏i=1k(x−1−i)
那么算 ∏ i = 1 k ( x − i ) = x k + 1 ‾ x \prod_{i=1}^k(x-i)=\frac{x^{\underline {k+1}}}{x} ∏i=1k(x−i)=xxk+1 即可。
复杂度 O ( n log n ) O(n\log n) O(nlogn)。
2.0 2.0 2.0 补充:概率生成函数
主要是抄一下概念。这玩意显然不是每道题都用的上,但是可以帮助我们更好的理解概率期望。
如果 X X X是非负整数集 N N N上的离散随机变量,那么 X X X的概率生成函数为:
F ( z ) = E ( z X ) = ∑ i = 0 ∞ P r ( X = i ) z i F(z)=E(z^X)=\sum_{i=0}^{\infty}Pr(X=i)z^i F(z)=E(zX)=∑i=0∞Pr(X=i)zi。
显然,只能处理非负整数集上的情况。
2.0.1 2.0.1 2.0.1 因为 X X X是非负整数集 N N N上的离散随机变量,所以必有 F ( 1 ) = ∑ i = 0 ∞ P r ( X = i ) = 1 F(1)=\sum_{i=0}^{\infty}Pr(X=i)=1 F(1)=∑i=0∞Pr(X=i)=1。
2.0.1 2.0.1 2.0.1 对 F ( z ) F(z) F(z)求导,得到 F ′ ( z ) = ∑ i = 0 ∞ i P r ( X = i ) z i − 1 F'(z)=\sum_{i=0}^{\infty}iPr(X=i)z^{i-1} F′(z)=∑i=0∞iPr(X=i)zi−1,所以 X X X的期望 E ( x ) = F ′ ( 1 ) = ∑ i = 0 ∞ i P r ( X = i ) E(x)=F'(1)=\sum_{i=0}^{\infty}iPr(X=i) E(x)=F′(1)=∑i=0∞iPr(X=i)。可以类比得到 E ( X k ‾ ) = F ( k ) ( 1 ) , k ≠ 0 E(X^{\underline{k}})=F^{(k)}(1),k\ne 0 E(Xk)=F(k)(1),k=0。所以 X X X的方差 D ( X ) = E ( X 2 ) − E 2 ( X ) = F ′ ′ ( 1 ) + F ′ ( 1 ) − ( F ′ ( 1 ) ) 2 D(X)=E(X^2)-E^2(X)=F''(1)+F'(1)-(F'(1))^2 D(X)=E(X2)−E2(X)=F′′(1)+F′(1)−(F′(1))2。
对于生成函数,我们最基本的方法就是列方程。
考虑这样一个问题,给你一个字符串 A A A,和一个初始为空的字符串 B B B,每次从 m m m个字符中随机选一个插入到 B B B的末尾直到 B B B字符串中包含 A A A,求 B B B的期望长度。
令 a i a_i ai表示 A [ 1 , i ] A[1,i] A[1,i]是否为 A A A的一个 border \text{border} border, f i f_i fi为结束时随机序列长度为 i i i的概率,其概率生成函数为 F ( x ) F(x) F(x)。考虑构造辅助数组 g i g_i gi为随机序列长度到达 i i i且还未结束的概率,其生成函数为 G ( x ) G(x) G(x)。
那么有如下等式: F ( x ) + G ( x ) = 1 + x ⋅ G ( x ) F(x)+G(x)=1+x\cdot G(x) F(x)+G(x)=1+x⋅G(x)。
但是只有一个等式显然是无法求解的。考虑算二次的思想,在一个任意串后面接上串 A A A,如果在某一位置停下了,那么我们就可以据此构造出一段 border \text{border} border(这可以形象的理解为从前面截断和从后面截断),那么有 G ( x ) ⋅ ( 1 m x ) L = ∑ a i ⋅ F ( x ) ⋅ ( 1 m x ) L − i G(x)\cdot (\frac{1}{m}x)^L=\sum a_i\cdot F(x)\cdot (\frac{1}{m}x)^{L-i} G(x)⋅(m1x)L=∑ai⋅F(x)⋅(m1x)L−i。(左边式子有 x x x注意不要抄掉了)
将第一个式子求导, F ′ ( x ) + G ′ ( x ) = x G ′ ( x ) + G ( x ) F'(x)+G'(x)=xG'(x)+G(x) F′(x)+G′(x)=xG′(x)+G(x),将 x = 1 x=1 x=1代入得到 F ′ ( 1 ) = G ( 1 ) F'(1)=G(1) F′(1)=G(1),再将 x = 1 x=1 x=1代入第二个式子得到 G ( 1 ) = ∑ a i ⋅ m i G(1)=\sum a_i\cdot m^i G(1)=∑ai⋅mi,我们要求的就是 F ′ ( 1 ) F'(1) F′(1),这道题就做完了。
这些技巧可以需要对生成函数比较熟悉才能熟练掌握。
求其中某一项可以用多项式求逆解决。有时间我再推一下。
__EOF__

本文链接:https://www.cnblogs.com/cqbzly/p/17530045.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」