跳转至

普通生成函数

序列 a 的普通生成函数(ordinary generating function,OGF)定义为形式幂级数:

F(x)=nanxn

a 既可以是有穷序列,也可以是无穷序列。常见的例子(假设 a0 为起点):

  1. 序列 a=1,2,3 的普通生成函数是 1+2x+3x2
  2. 序列 a=1,1,1, 的普通生成函数是 n0xn
  3. 序列 a=1,2,4,8,16, 的生成函数是 n02nxn
  4. 序列 a=1,3,5,7,9, 的生成函数是 n0(2n+1)xn

换句话说,如果序列 a 有通项公式,那么它的普通生成函数的系数就是通项公式。

基本运算

考虑两个序列 a,b 的普通生成函数,分别为 F(x),G(x)。那么有

F(x)±G(x)=n(an±bn)xn

因此 F(x)±G(x) 是序列 an±bn 的普通生成函数。

考虑乘法运算,也就是卷积:

F(x)G(x)=nxni=0naibni

因此 F(x)G(x) 是序列 i=0naibni 的普通生成函数。

封闭形式

在运用生成函数的过程中,我们不会一直使用形式幂级数的形式,而会适时地转化为封闭形式以更好地化简。

例如 1,1,1, 的普通生成函数 F(x)=n0xn,我们可以发现

F(x)x+1=F(x)

那么解这个方程得到

F(x)=11x

这就是 n0xn 的封闭形式。

考虑等比数列 1,p,p2,p3,p4, 的生成函数 F(x)=n0pnxn,有

F(x)px+1=F(x)F(x)=11px

等比数列的封闭形式与展开形式是常用的变换手段。

小练习

请求出下列数列的普通生成函数(形式幂级数形式和封闭形式)。难度是循序渐进的。

  1. a=0,1,1,1,1,
  2. a=1,0,1,0,1,
  3. a=1,2,3,4,
  4. an=(mn)m 是常数,n0)。
  5. an=(m+nn)m 是常数,n0)。
答案

第一个:

F(x)=n1xn=x1x

第二个:

F(x)=n0x2n=n0(x2)n=11x2

第三个(求导):

F(x)=n0(n+1)xn=n1nxn1=n0(xn)=(11x)=1(1x)2

第四个(二项式定理):

F(x)=n0(mn)xn=(1+x)m

第五个:

F(x)=n0(m+nn)xn=1(1x)m+1

可以使用归纳法证明。

首先当 m=0 时,有 F(x)=11x

而当 m>0 时,有

1(1x)m+1=1(1x)m11x=(n0(m+n1n)xn)(n0xn)=n0xni=0n(m+i1i)=n0(m+nn)xn

斐波那契数列的生成函数

接下来我们来推导斐波那契数列的生成函数。

斐波那契数列定义为 a0=0,a1=1,an=an1+an2(n>1)。设它的普通生成函数是 F(x),那么根据它的递推式,我们可以类似地列出关于 F(x) 的方程:

F(x)=xF(x)+x2F(x)a0x+a1x+a0

那么解得

F(x)=x1xx2

那么接下来的问题是,如何求出它的展开形式?

展开方式一

不妨将 x+x2 当作一个整体,那么可以得到

F(x)=x1(x+x2)=n0(x+x2)n=n0i=0n(ni)x2ixni=n0i=0n(ni)xn+i=n0xni=0n(nii)

我们得到了 an 的通项公式,但那并不是我们熟知的有关黄金分割比的形式。

展开方式二

考虑求解一个待定系数的方程:

A1ax+B1bx=x1xx2

通分得到

AAbx+BaBx(1ax)(1bx)=x1xx2

待定项系数相等,我们得到

{A+B=0AbaB=1a+b=1ab=1

解得

{A=15B=15a=1+52b=152

那么我们根据等比数列的展开式,就可以得到斐波那契数列的通项公式:

x1xx2=n0xn15((1+52)n(152)n)

这也被称为斐波那契数列的另一个封闭形式(x1xx2 是一个封闭形式)。

对于任意多项式 P(x),Q(x),生成函数 P(x)Q(x) 的展开式都可以使用上述方法求出。在实际运用的过程中,我们往往先求出 Q(x) 的根,把分母表示为 (1pix)di 的形式,然后再求分子。

当对分母进行因式分解但有重根时,每有一个重根就要多一个分式,如考虑生成函数

G(x)=1(1x)(12x)2

的系数的通项公式,那么有

G(x)=c01x+c112x+c2(12x)2

解得

{c0=1c1=2c2=2

那么

[xn]G(x)=12n+1+(n+1)2n+1

牛顿二项式定理

我们重新定义组合数的运算:

(rk)=rkk!(rC,kN)

注意 r 的范围是复数域。在这种情况下。对于 αC,有

(1+x)α=n0(αn)xn

二项式定理其实是牛顿二项式定理的一个特殊情况。

卡特兰数的生成函数

参考 Catalan 数的封闭形式

应用

接下来给出一些例题,来介绍生成函数在 OI 中的具体应用。

食物

食物

在许多不同种类的食物中选出 n 个,每种食物的限制如下:

  1. 承德汉堡:偶数个
  2. 可乐:0 个或 1 个
  3. 鸡腿:0 个,1 个或 2 个
  4. 蜜桃多:奇数个
  5. 鸡块:4 的倍数个
  6. 包子:0 个,1 个,2 个或 3 个
  7. 土豆片炒肉:不超过一个。
  8. 面包:3 的倍数个

每种食物都是以「个」为单位,只要总数加起来是 n 就算一种方案。对于给出的 n 你需要计算出方案数,对 10007 取模。

这是一道经典的生成函数题。对于一种食物,我们可以设 an 表示这种食物选 n 个的方案数,并求出它的生成函数。而两种食物一共选 n 个的方案数的生成函数,就是它们生成函数的卷积。多种食物选 n 个的方案数的生成函数也是它们生成函数的卷积。

在理解了方案数可以用卷积表示以后,我们就可以构造生成函数(标号对应题目中食物的标号):

  1. n0x2n=11x2
  2. 1+x
  3. 1+x+x2=1x31x
  4. x1x2
  5. n0x4n=11x4
  6. 1+x+x2+x3=1x41x
  7. 1+x
  8. 11x3

那么全部乘起来,得到答案的生成函数:

F(x)=(1+x)(1x3)x(1x4)(1+x)(1x2)(1x)(1x2)(1x4)(1x)(1x3)=x(1x)4

然后将它转化为展开形式(使用封闭形式练习中第五个练习):

F(x)=n1(n+2n1)xn

因此答案就是 (n+2n1)=(n+23)

Sweet

「CEOI2004」Sweet

n 堆糖果。不同的堆里糖果的种类不同(即同一个堆里的糖果种类是相同的,不同的堆里的糖果的种类是不同的)。第 i 个堆里有 mi 个糖果。现在要吃掉至少 a 个糖果,但不超过 b 个。求有多少种方案。

两种方案不同当且仅当吃的个数不同,或者吃的糖果中,某一种糖果的个数在两个方案中不同。

n10,0ab107,mi106

在第 i 堆吃 j 个糖果的方案数(显然为 1)的生成函数为

Fi(x)=j=0mixj=1xmi+11x

因此总共吃 i 个糖果的方案数的生成函数就是

G(x)=i=1nFi(x)=(1x)ni=1n(1xmi+1)

现在我们要求的是 i=ab[xi]G(x)

由于 n10,因此我们可以暴力展开 i=1n(1xmi+1)(最多只有 2n 项)。

然后对 (1x)n 使用牛顿二项式定理:

(1x)n=i0(ni)(x)i=i0(n1+ii)xi

我们枚举 i=1n(1xmi+1)xk 项的系数,假设为 ck。那么它和 (1x)n 相乘后,对答案的贡献就是

cki=akbk(n1+ii)=ck((n+bkbk)(n+ak1ak1))

这样就可以 O(b) 地求出答案了。

时间复杂度 O(2n+b)