Zscoder‘s 生成函数教程(一)

Zscoder’s 生成函数教程(一)

本文翻译自 zscoder 的 CF Blog 文章 [Tutorial] Generating Functions in Competitive Programming (Part 1)

本文是原文的第一部分中的前半段,生成函数入门。

如有侵权,联系作者将尽快删除;如有翻译不足之处,敬请指出。

什么是生成函数

现在我们有一个数列 a 0 , a 1 , a 2 , … a_0,a_1,a_2,\ldots a0,a1,a2, 。我们通过构建数列项和多项式中项的系数的关系将数列 a a a 和多项式 A A A 关联起来。

一般的,对于一个数列 { a i } i = 0 ∞ \{a_i\}^{\infty}_{i=0} {ai}i=0 我们定义这个数列的 一般生成函数(OGF) A ( x ) = ∑ i = 0 ∞ a i x i A(x) = \sum^{\infty}_{i=0} a_i x^i A(x)=i=0aixi

例如,考虑斐波那契数列 f f f 0 , 1 , 1 , 2 , 3 , 5 , 8 , … 0,1,1,2,3,5,8,\ldots 0,1,1,2,3,5,8, 。那么 F ( x ) = 0 + x + x 2 + 2 x 3 + 3 x 4 + 5 x 5 + 8 x 6 + … F(x) = 0 + x + x^{2} + 2x^{3} + 3x^{4} + 5x^{5} + 8x^{6} + \ldots F(x)=0+x+x2+2x3+3x4+5x5+8x6+

你可以想象是将数列中的每一项(可能无限)按序放入多项式中的每一项系数中。通过把多项式中每一项都加起来,你就会得到一个系数为数列中的每一项构成的“无穷多项式”。这种构建生成函数的好处在于通过生成函数你会发现一些在普通数列中处理技巧中没有但是令人吃惊的一些特性。

实际上有很多种生成函数,例如指数生成函数(EGF)和狄利克雷生成函数。在本文的最后我们将会看到一些关于指数生成函数的例子,但是现在我们重点关心普通生成函数并给出一些经典的例子。

在那之前,我们为了方便引入一种记号。对于多项式 A ( x ) = ∑ n ≥ 0 a n x n A(x) = \sum_{n \ge 0} a_n x^n A(x)=n0anxn ,我们记 [ x n ] A ( x ) = a n [x^n]A(x) = a_n [xn]A(x)=an (也就是说在 A A A x n x^n xn 的系数)。

OGF的一些简单例子

让我们从一个非常简单的例子开始。数列 1 , 1 , 1 , 1 , … 1,1,1,1,\ldots 1,1,1,1, 的 OGF 是什么?根据定义,我们有 A ( x ) = 1 + x + x 2 + x 3 + … A(x) = 1+x+x^{2}+x^{3}+ \ldots A(x)=1+x+x2+x3+ ,是不是看起来很眼熟?

A ( x ) A(x) A(x) 实际上是一个公比为 x x x 的几何级数。因此根据等比数列求和公式,我们有 A ( x ) = 1 1 − x A(x) = \frac{1}{1-x} A(x)=1x1

注意:我们不关心级数的收敛问题,例如 ∣ x ∣ < 1 |x| \lt 1 x<1 是否成立?其实,这取决你使用级数想干什么。现在,在生成函数和大多数情况下,我们将级数视为 形式幂级数 ,我们不需要关心形式幂级数的敛散性问题。然而,这并不意味着就可以随便将参数 x x x 带入任意常数。例如,当 x = 2 x=2 x=2 的时候,级数 A ( x ) A(x) A(x) 发散,但是当 x = − 1 2 x = -\frac{1}{2} x=21 的时候,级数收敛。在本文中,大多数情况我们不讨论级数的解析性质。如果你确实需要带入值到 x x x 中,你最好注意级数是否在 x x x 处收敛。

我们可以像操纵其他代数式一样的方式和技巧操纵生成函数式,下面是一些典型的例子。

斐波那契数列的普通生成函数

考虑数列 f n f_n fn 定义为 f 0 = 0 , f 1 = 1 f_0 = 0,f_1=1 f0=0,f1=1 并且 f n = f n − 1 + f n − 2 f_n = f_{n-1} + f_{n-2} fn=fn1+fn2 对于 n > 2 n \gt 2 n>2 。请计算 f n f_n fn 的生成函数的封闭形式。

显然, f n f_n fn 就是我们熟悉的斐波那契数列。我们将使用斐波那契的递归式来计算生成函数。

首先,为了凑出多项式的形式,最简单的方法就是等式两边同时乘以 x n x^n xn 来得到 f n x n = f n − 1 x n + f n − 2 x n f_{n}x^{n} = f_{n-1}x^{n} + f_{n-2}x^{n} fnxn=fn1xn+fn2xn

接下来,我们对两个同时求和(注意 n ≥ 2 n \ge 2 n2 ):

∑ n = 2 ∞ f n x n = x ∑ n = 2 ∞ f n − 1 x n − 1 + x 2 ∑ n = 2 ∞ f n − 2 x n − 2 \displaystyle\sum_{n=2}^{\infty}f_{n}x^{n} = x\displaystyle\sum_{n=2}^{\infty}f_{n-1}x^{n-1} + x^{2}\displaystyle\sum_{n=2}^{\infty}f_{n-2}x^{n-2} n=2fnxn=xn=2fn1xn1+x2n=2fn2xn2

这等于:

F ( x ) − f 0 x 0 − f 1 x 1 = x ( F ( x ) − f 0 x 0 ) + x 2 F ( x ) ⇒ F ( x ) − x = ( x + x 2 ) F ( x ) ⇒ F ( x ) ( 1 − x − x 2 ) = x ⇒ F ( x ) = x 1 − x − x 2 \begin{align*} & F(x) - f_{0}x^{0} - f_{1}x^{1} = x(F(x) - f_{0}x^{0}) + x^{2}F(x) \\ & \Rightarrow F(x) - x = (x+x^2)F(x) \\ & \Rightarrow F(x)(1-x-x^2)=x \\ & \Rightarrow F(x) = \frac{x}{1-x-x^2} \end{align*} F(x)f0x0f1x1=x(F(x)f0x0)+x2F(x)F(x)x=(x+x2)F(x)F(x)(1xx2)=xF(x)=1xx2x

这就是斐波那契的生成函数的 封闭形式

让我们看看其他例子。

Catalan数列的普通生成函数

Catalan 数列 c n c_n cn 定义为 c 0 = 1 c_0 = 1 c0=1 并且 c n + 1 = ∑ i = 0 n c i c n − i c_{n+1} = \sum_{i=0}^{n} c_ic_{n-i} cn+1=i=0ncicni 对于 n > 0 n \gt 0 n>0 。计算其生成函数的封闭形式。

再次使用我们的策略,得到:

∑ n = 0 ∞ c n + 1 x n + 1 = ∑ n = 0 ∞ ∑ i = 0 n c i c n − i x n + 1 = x ∑ n = 0 ∞ ∑ i = 0 n c i x i c n − i x n − i \displaystyle\sum_{n=0}^{\infty}c_{n+1}x^{n+1} = \displaystyle\sum_{n=0}^{\infty}\sum_{i=0}^{n}c_{i}c_{n-i}x^{n+1} = \displaystyle x\sum_{n=0}^{\infty}\sum_{i=0}^{n}c_{i}x^{i}c_{n-i}x^{n-i} n=0cn+1xn+1=n=0i=0ncicnixn+1=xn=0i=0ncixicnixni

等式左边很好解释,它就是 C ( x ) − c 0 = C ( x ) − 1 C(x) - c_0 = C(x) - 1 C(x)c0=C(x)1

那对于等式右边呢?考虑 C ( x ) 2 C(x)^2 C(x)2 的展开式中 x n x^n xn 的系数是多少?如果我们将 C ( x ) 2 C(x)^2 C(x)2 展开为 C ( x ) 2 = ( c 0 + c 1 x + c 2 x 2 + …   ) ( c 0 + c 1 x + c 2 x 2 + …   ) C(x)^2 = (c_{0}+c_{1}x+c_{2}x^2+\dots)(c_{0}+c_{1}x+c_{2}x^2+\dots) C(x)2=(c0+c1x+c2x2+)(c0+c1x+c2x2+) 我们发现可以通过在第一个括号中选取 c i x i c_ix^i cixi 而在第二个括号中选取 c n − i x n − i c_{n-i}x^{n-i} cnixni 可以得到 C ( x ) 2 C(x)^2 C(x)2 中的 x n x^n xn 项系数为 ∑ i = 0 n c i c n − i \displaystyle\sum_{i=0}^{n}c_{i}c_{n-i} i=0ncicni 。这正是上面等式右边级数的系数。因此,上述等式右边即为 x C ( x ) 2 xC(x)^2 xC(x)2

因此,我们得到 C ( x ) − 1 = x C ( x ) 2 C(x) - 1= xC(x)^2 C(x)1=xC(x)2 ,注意这是一个关于 C ( x ) C(x) C(x) 的一个一元二次方程,解得 C ( x ) = 1 ± 1 − 4 x 2 x C(x) = \frac{1 \pm \sqrt{1-4x}}{2x} C(x)=2x1±14x 。现在的问题是,分子中的符号应取正号还是符负号?如果我们取正号,当 x → 0 x \to 0 x0 的时候分子 → 2 \to 2 2 而分母 → 0 \to 0 0 ,这说明级数在 x = 0 x = 0 x=0 出发散。但是根据定义 c 0 = 1 c_0 = 1 c0=1 这说明级数应该在 x = 0 x=0 x=0 处收敛至 1 1 1 才对。因此我们必须取负号得到 C ( x ) = 1 − 1 − 4 x 2 x C(x) = \frac{1 - \sqrt{1-4x}}{2x} C(x)=2x114x (实际上,根据洛必达法则可知当 x = 0 x=0 x=0 的时候 c 0 = 1 c_0 = 1 c0=1 )。

提示:尝试寻找一些你见过的经典数列,并计算他们的生成函数的封闭形式。这有助于你形成看到函数递归式就能想到生成函数的直觉。

多变量参数的OGF

我们并没有限制 OGF 的变量参数个数。这意味着存在多变量参数的 OGF 。让我们看一些例子吧。

二项式系数的OGF

二项式系数 b ( n , k ) = ( n k ) b(n,k) = \binom{n}{k} b(n,k)=(kn) 被定义为 b ( n , 0 ) = 1 b(n,0) = 1 b(n,0)=1 对于 n ≥ 0 n \ge 0 n0 b ( 0 , n ) = 0 b(0,n) = 0 b(0,n)=0 对于 n ≥ 1 n \ge 1 n1 并且 b ( n , k ) = b ( n − 1 , k ) + b ( n − 1 , k − 1 ) b(n,k) = b(n-1,k) + b(n-1,k-1) b(n,k)=b(n1,k)+b(n1,k1) 对于 n , k ≥ 1 n,k \ge 1 n,k1 。计算 b ( n , k ) b(n,k) b(n,k) 的生成函数的封闭形式。

我们定义 B ( x , y ) B(x,y) B(x,y) 的展开形式为 ∑ n ≥ 0 ∑ k ≥ 0 b ( n , k ) x n y k \sum_{n \ge 0}\sum_{k \ge 0}b(n,k)x^ny^k n0k0b(n,k)xnyk 。同样使用我们之前的策略,我们有:

∑ n ≥ 1 ∑ k ≥ 1 b ( n , k ) x n y k = x ∑ n ≥ 1 ∑ k ≥ 1 b ( n − 1 , k ) x n − 1 y k + x y ∑ n ≥ 1 ∑ k ≥ 1 b ( n − 1 , k − 1 ) x n − 1 y k − 1 \displaystyle\sum_{n \ge 1}\sum_{k \ge 1}b(n,k)x^{n}y^{k} = x\displaystyle\sum_{n \ge 1}\sum_{k \ge 1}b(n-1,k)x^{n-1}y^{k} + xy\displaystyle\sum_{n \ge 1}\sum_{k \ge 1}b(n-1,k-1)x^{n-1}y^{k-1} n1k1b(n,k)xnyk=xn1k1b(n1,k)xn1yk+xyn1k1b(n1,k1)xn1yk1

因此,我们有:

B ( x , y ) − ∑ n ≥ 0 x n = x ( B ( x , y ) − ∑ n ≥ 0 x n ) + x y B ( x , y ) ⇒ B ( x , y ) − 1 1 − x = ( x + x y ) B ( x , y ) − x 1 − x ⇒ ( 1 − x − x y ) B ( x , y ) = 1 ⇒ B ( x , y ) = 1 1 − x − x y \begin{align*} & B(x,y) - \displaystyle\sum_{n \ge 0}x^{n} = x(B(x,y) - \displaystyle\sum_{n \ge 0}x^{n}) + xyB(x,y) \\ & \Rightarrow B(x,y) - \frac{1}{1-x} = (x+xy)B(x,y) - \frac{x}{1-x} \\ & \Rightarrow (1-x-xy)B(x,y) = 1 \\ & \Rightarrow B(x,y) = \frac{1}{1-x-xy} \end{align*} B(x,y)n0xn=x(B(x,y)n0xn)+xyB(x,y)B(x,y)1x1=(x+xy)B(x,y)1xx(1xxy)B(x,y)=1B(x,y)=1xxy1

根据上面的多变量参数 OGF ,我们可以推导出很多有趣的一元变量参数的 OGF 。例如,我们将 B ( x , y ) B(x,y) B(x,y) 看做是关于 x x x 的幂级数,将 y y y 视为常量:

B ( x , y ) = 1 1 − x − x y = 1 1 − x ( y + 1 ) = ∑ k ≥ 0 ( y + 1 ) k x k B(x,y) = \frac{1}{1-x-xy} = \frac{1}{1 - x(y+1)} = \displaystyle\sum_{k \ge 0}(y+1)^{k}x^{k} B(x,y)=1xxy1=1x(y+1)1=k0(y+1)kxk

因此, [ x n ] B ( x , y ) = ( y + 1 ) n [x^{n}]B(x,y) = (y+1)^{n} [xn]B(x,y)=(y+1)n 。然而根据定义, [ x n ] B ( x , y ) = ∑ k = 0 ∞ b ( n , k ) y k [x^{n}]B(x,y) = \displaystyle\sum_{k=0}^{\infty}b(n,k)y^{k} [xn]B(x,y)=k=0b(n,k)yk ,所以 ∑ k = 0 ∞ b ( n , k ) y k = ( y + 1 ) n \displaystyle\sum_{k=0}^{\infty}b(n,k)y^{k} = (y+1)^{n} k=0b(n,k)yk=(y+1)n 。注意这和对 ( y + 1 ) n (y+1)^{n} (y+1)n 进行二项式展开得到的结果 ( y + 1 ) n = ( n 0 ) y 0 + ( n 1 ) y 1 + … + ( n n ) y n (y+1)^{n} = \binom{n}{0}y^{0}+\binom{n}{1}y^{1}+\ldots+\binom{n}{n}y^{n} (y+1)n=(0n)y0+(1n)y1++(nn)yn 一样。

B ( x , y ) B(x,y) B(x,y) 看做是 y y y 的幂级数将更加有趣,我们有:

B ( x , y ) = 1 ( 1 − x ) − x y = 1 1 − x 1 − x 1 − x y = 1 1 − x ( 1 + x 1 − x y + ( x 1 − x ) 2 y 2 + … ) B(x,y) = \frac{1}{(1-x)-xy} = \frac{\frac{1}{1-x}}{1-\frac{x}{1-x}y} = \frac{1}{1-x}(1 + \frac{x}{1-x}y + (\frac{x}{1-x})^2y^2 + \ldots) B(x,y)=(1x)xy1=11xxy1x1=1x1(1+1xxy+(1xx)2y2+)

因此, [ y k ] B ( x , y ) = x k ( 1 − x ) k + 1 [y^{k}]B(x,y) = \frac{x^{k}}{(1-x)^{k+1}} [yk]B(x,y)=(1x)k+1xk ,同样的和定义比较,我们要有:

∑ n = 0 ∞ b ( n , k ) x n = x k ( 1 − x ) k + 1 \displaystyle\sum_{n=0}^{\infty}b(n,k)x^{n} = \frac{x^{k}}{(1-x)^{k+1}} n=0b(n,k)xn=(1x)k+1xk

这是一个非常有意思的等式,因为这个等式告诉我们 1 ( 1 − x ) k + 1 \frac{1}{(1-x)^{k+1}} (1x)k+11 应该怎么展开,特别的, [ x n − k ] 1 ( 1 − x ) k + 1 = ( n k ) [x^{n-k}]\frac{1}{(1-x)^{k+1}} = \binom{n}{k} [xnk](1x)k+11=(kn) ,因此 [ x n ] 1 ( 1 − x ) k = ( n + k − 1 k − 1 ) [x^{n}]\frac{1}{(1-x)^{k}} = \binom{n+k-1}{k-1} [xn](1x)k1=(k1n+k1) 。这个等式在当我们处理包含二项式系数求和的时候并且 k k k 是固定的而 n n n 是变量的时候是非常有用的。

指数生成函数

到目前为止,我们已经看了很多关于普通生成函数的例子了。现在,让我们介绍一个全新的生成函数叫做 指数生成函数

定义:让 a 0 , a 1 , a 2 , … a_0,a_1,a_2,\ldots a0,a1,a2, 是一个数列。然后,数列 a a a 的指数生成函数定义为 A ( x ) = ∑ i = 0 ∞ a i i ! x i A(x) = \sum_{i=0}^{\infty} \frac{a_i}{i!} x^i A(x)=i=0i!aixi

换句话说,指数生成函数仅仅是在普通生成函数的基础上,将系数除以 i ! i! i! 。为什么偏偏选择 i ! i! i! ?下面的例子我们将会揭晓这个明智的选择。

Bell 数的指数生成函数

b n b_n bn 是第 n n n 个 Bell 数,Bell 数指的是将集合 { 1 , 2 , 3 , … , n } \{1,2,3,\ldots,n\} {1,2,3,,n} 拆成不相交集合的方案数。例如 b 3 = 5 b_3=5 b3=5 ,集合 { 1 , 2 , 3 } \{1,2,3\} {1,2,3} 可以拆成 123 ; 12 , 3 ; 13 , 2 ; 1 , 23 ; 1 , 2 , 3 123;12,3;13,2;1,23;1,2,3 123;12,3;13,2;1,23;1,2,3 。计算其指数生成函数。

我们的第一步是寻找数列的递归式。假设你在做一个 Div.2 的 C 题,思考一下使用 DP 怎么做。

我们设元素 1 1 1 所在的集合大小为 i i i ,那么划分剩下的 n − i n - i ni 个元素的方案数为 b n − i b_{n-i} bni ,选择 i − 1 i-1 i1 个元素的方案数为 ( n − 1 i − 1 ) \binom{n-1}{i-1} (i1n1) 。根据乘法原理和加法原理,我们有:

b n = ∑ i = 1 n ( n − 1 i − 1 ) b n − i = ∑ i = 0 n − 1 ( n − 1 i ) b i , ( n ≥ 1 ) b_{n} = \displaystyle\sum_{i=1}^{n}\binom{n-1}{i-1}b_{n-i} = \displaystyle\sum_{i=0}^{n-1}\binom{n-1}{i}b_{i} ,(n \ge 1) bn=i=1n(i1n1)bni=i=0n1(in1)bi,(n1)

通过预处理二项式系数,这是一个 O ( n 2 ) O(n^2) O(n2) 的 DP。对于 Div.2 C 来说大多数情况是足够的。那如果数据范围是 n ≤ 3 × 1 0 5 n \le 3 \times 10^5 n3×105 该怎么办呢?

答案就是利用指数生成函数,注意到:

b n = ∑ i = 0 n − 1 ( n − 1 i ) b i = ∑ i = 0 n − 1 ( n − 1 ) ! i ! ( n − 1 − i ) ! b i ⇒ n b n n ! = ∑ i = 0 n − 1 b i i ! 1 ( n − 1 − i ) ! ⇒ ∑ n ≥ 1 n b n n ! x n = ∑ n ≥ 1 x ∑ i = 0 n − 1 b i x i i ! x n − 1 − i ( n − 1 − i ) ! \begin{align*} & b_{n} = \displaystyle\sum_{i=0}^{n-1}\binom{n-1}{i}b_{i} = \displaystyle\sum_{i=0}^{n-1}\frac{(n-1)!}{i!(n-1-i)!}b_{i} \\ & \Rightarrow n\frac{b_{n}}{n!} = \displaystyle\sum_{i=0}^{n-1}\frac{b_i}{i!}\frac{1}{(n-1-i)!} \\ & \Rightarrow \displaystyle\sum_{n \ge 1}n\frac{b_{n}}{n!}x^{n} = \displaystyle\sum_{n \ge 1} x\displaystyle\sum_{i=0}^{n-1}\frac{b_{i}x^{i}}{i!}\frac{x^{n-1-i}}{(n-1-i)!} \end{align*} bn=i=0n1(in1)bi=i=0n1i!(n1i)!(n1)!binn!bn=i=0n1i!bi(n1i)!1n1nn!bnxn=n1xi=0n1i!bixi(n1i)!xn1i

现在我们看到了,为什么指数生成函数对于上面的问题很方便。如果我们的卷积包含二项式系数(通常我们在处理组合问题的时候会遇到),那么使用 EGF 将会自动帮助我们对齐卷积形式(详见后面的卷积部分)。

回到我们的问题,我们想计算 B ( x ) B(x) B(x) ,那么对于等式右边是显然的(计算 B ( x ) B(x) B(x) e x e^x ex 的卷积 ),因为他就是 x B ( x ) e x xB(x)e^x xB(x)ex (回忆一下 e x e^x ex 的麦克劳林展开式是 ∑ n ≥ 0 x n n ! \sum_{n \ge 0} \frac{x^n}{n!} n0n!xn )。然而,等式左边的可能需要一点工作,因为我们有一个讨厌的 n b n nb_n nbn 而不是 b n b_n bn 。处理这个问题,我们要需要使用一个处理幂级数常见的一个技巧。让我们对于 B ( x ) B(x) B(x) 求导 ,然后在乘以 x x x。验证一下就是,令 A ( x ) = a 0 + a 1 x 1 + a 2 x 2 + … = ∑ n ≥ 0 a n x n A(x) = a_{0}+a_{1}x^{1}+a_{2}x^{2}+\ldots = \displaystyle\sum_{n \ge 0}a_{n}x^{n} A(x)=a0+a1x1+a2x2+=n0anxn 是幂级数,那么 x A ’ ( x ) = a 1 x 1 + 2 a 2 x 2 + 3 a 3 x 3 + … = ∑ n ≥ 0 n a n x n xA’(x) = a_{1}x^{1} + 2a_{2}x^{2} + 3a_{3}x^{3} +\ldots= \displaystyle\sum_{n \ge 0}na_{n}x^{n} xA(x)=a1x1+2a2x2+3a3x3+=n0nanxn

现在让我们回头看看这个方程就是 x B ′ ( x ) = x B ( x ) e x xB'(x)=xB(x)e^x xB(x)=xB(x)ex ,也就是 B ′ ( x ) B ( x ) = e x \frac{B'(x)}{B(x)} = e^x B(x)B(x)=ex 。如果你对微积分很擅长的话(特别是微分方程),你就会知道同时对两边积分可得 ln ⁡ B ( x ) = e x + c \ln B(x) = e^x + c lnB(x)=ex+c 。因为 b 0 = 1 , B ( 0 ) = 1 b_0 = 1, B(0) = 1 b0=1,B(0)=1 解得 c = − 1 c = -1 c=1 。因此, B ( x ) = e e x − 1 B(x) = e^{e^x - 1} B(x)=eex1 就是我们想要的 EGF ,可能在形式上看起来有点奇怪。

所以,如何比 O ( n 2 ) O(n^2) O(n2) 更快的计算 b n b_n bn ?在学习过多项式算法之后,我们知道可以在 O ( n log ⁡ n ) O(n \log n) O(nlogn) 的时间内计算出多项式 e P ( x ) e^{P(x)} eP(x) 的前 n n n 项系数。在本教程的第二部分,我们默认你已经学会了基本的多项式算法,例如在 O ( n log ⁡ n ) O(n \log n) O(nlogn) O ( n log ⁡ 2 n ) O(n \log^2 n) O(nlog2n) 的时间下计算出 P ( x ) , ln ⁡ P ( x ) \sqrt{P(x)},\ln P(x) P(x) ,lnP(x) 等多项式的系数。

生成函数的代数技巧

这有许多操纵生成函数的方法。在这节, a i a_i ai b i b_i bi 将代表生成函数 A ( x ) A(x) A(x) B ( x ) B(x) B(x) 的第 i i i 项系数(是 OGF 还是 EGF 取决于具体情况)。作为练习,请验证这些表达式。

加法

对于生成函数, C ( x ) = A ( x ) + B ( x ) C(x) = A(x) + B(x) C(x)=A(x)+B(x) 生成数列 c n = a n + b n c_n = a_n + b_n cn=an+bn

平移

对于 OGF, C ( x ) = x k A ( x ) C(x) = x^k A(x) C(x)=xkA(x) 生成数列 c n = a n − k , ( a i = 0 , i < 0 ) c_n = a_{n-k},(a_i = 0,i \lt 0) cn=ank,(ai=0,i<0) 。对于 EGF,你需要对 A ( x ) A(x) A(x) 积分 k k k 次来达到同样的效果。

对于 OGF, C ( x ) = A ( x ) − ( a 0 + a 1 x 1 + a 2 x 2 + … + a k − 1 x k − 1 ) x k C(x) = \frac{A(x) - (a_0+a_1x^1+a_2x^2+\ldots+a_{k-1}x^{k-1})}{x^k} C(x)=xkA(x)(a0+a1x1+a2x2++ak1xk1) 生成数列 c n = a n + k c_n = a_{n+k} cn=an+k

对于 EGF, C ( x ) = A ( k ) ( x ) C(x)=A^{(k)}(x) C(x)=A(k)(x) 生成数列 c n = a n + k c_n = a_{n+k} cn=an+k ,这里 A ( k ) A^{(k)} A(k) 指的是对 A ( x ) A(x) A(x) 求导 n n n 次。

乘以 n n n

对于 OGF 和 EGF, C ( x ) = x C ′ ( x ) C(x) = xC'(x) C(x)=xC(x) 生成数列 c n = n a n c_n = na_n cn=nan

卷积

卷积对于生成函数来说是相当重要的一个操作。

对于 OGF 来说, C ( x ) = A ( x ) B ( x ) C(x) = A(x)B(x) C(x)=A(x)B(x) 生成数列 c n = ∑ k = 0 n a k b n − k c_n = \sum_{k=0}^{n} a_kb_{n-k} cn=k=0nakbnk

对于 EGF 来说, C ( x ) = A ( x ) B ( x ) C(x) = A(x)B(x) C(x)=A(x)B(x) 生成数列 c n = ∑ k = 0 n ( n k ) a k b n − k c_n = \sum_{k=0}^n \binom{n}{k}a_kb_{n-k} cn=k=0n(kn)akbnk (务必自己推导一下!)。

这也是为什么之前说 EGF 能够处理带二项式系数或是阶乘的递归式。

生成函数的幂

生成函数的幂也是卷积的一种形式,称为自卷积。

对于 OGF, C ( x ) = A ( x ) k C(x) = A(x)^k C(x)=A(x)k 生成数列 c n = ∑ i 1 + i 2 + … + i k = n a i 1 a i 2 … a i k c_n = \sum_{i_1+i_2+\ldots+i_k = n}a_{i_1}a_{i_2}\ldots a_{i_k} cn=i1+i2++ik=nai1ai2aik

对于 EGF, C ( x ) = A ( x ) k C(x) = A(x)^k C(x)=A(x)k 生成数列 c n = ∑ i 1 + i 2 + … + i k = n n ! i 1 ! i 2 ! … i k ! a i 1 a i 2 … a i k c_n = \sum_{i_1+i_2+\ldots+i_k = n} \frac{n!}{i_1!i_2!\ldots i_k!} a_{i_1}a_{i_2}\ldots a_{i_k} cn=i1+i2++ik=ni1!i2!ik!n!ai1ai2aik

前缀和技巧

前缀和技巧只对 OGF 有效,但是也值得了解一些。假设我们想构造数列 c n = a 0 + a 1 + a 2 + … + a n c_n = a_0 + a_1 + a_2 + \ldots + a_n cn=a0+a1+a2++an 。那么我们可以令 C ( x ) = 1 1 − x A ( x ) C(x) = \frac{1}{1-x} A(x) C(x)=1x1A(x)

其实就是 ∑ n ≥ 0 x n \sum_{n \ge 0} x^n n0xn ∑ n ≥ 0 a n x n \sum_{n \ge 0} a_n x^n n0anxn 做卷积。

常见数列的生成函数

单位常系数数列生成函数:

1 1 − x = 1 + x + x 2 + . . . = ∑ n ≥ 0 x n \frac{1}{1-x} = 1 + x + x^{2} + ... = \displaystyle\sum_{n \ge 0}x^{n} 1x1=1+x+x2+...=n0xn

调和数列生成函数:

− ln ⁡ ( 1 − x ) = x + x 2 2 + x 3 3 + . . . = ∑ n ≥ 1 x n n -\ln (1-x) = x + \frac{x^2}{2} + \frac{x^3}{3} + ... = \displaystyle\sum_{n \ge 1}\frac{x^{n}}{n} ln(1x)=x+2x2+3x3+...=n1nxn

单位常系数数列的 EGF( e x e^x ex 的麦克劳林展开):

e x = 1 + x + x 2 2 ! + x 3 3 ! + . . . = ∑ n ≥ 0 x n n ! e^{x} = 1 + x + \frac{x^2}{2!} + \frac{x^3}{3!} + ... = \displaystyle\sum_{n \ge 0}\frac{x^{n}}{n!} ex=1+x+2!x2+3!x3+...=n0n!xn

二项式系数的列向数列的生成函数:

( 1 − x ) − k = ( k − 1 0 ) x 0 + ( k 1 ) x 1 + ( k + 1 2 ) x 2 + . . . = ∑ n ( n + k − 1 n ) x n (1-x)^{-k} = \binom{k-1}{0}x^{0} + \binom{k}{1}x^{1} + \binom{k+1}{2}x^{2} + ... = \displaystyle\sum_{n}\binom{n+k-1}{n}x^{n} (1x)k=(0k1)x0+(1k)x1+(2k+1)x2+...=n(nn+k1)xn

我们的目的就是将复杂的函数转换到我们已知的 OGF 或是 EGF 的封闭形式上去。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值