普通生成函数

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

F(x)=∑nanxnF(x)=\sum_{n}a_n x^n

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

  1. 序列 a=⟨1,2,3⟩a=\langle 1,2,3\rangle 的普通生成函数是 1+2x+3x21+2x+3x^2.
  2. 序列 a=⟨1,1,1,⋯ ⟩a=\langle 1,1,1,\cdots\rangle 的普通生成函数是 ∑n≥0xn\sum_{n\ge 0}x^n.
  3. 序列 a=⟨1,2,4,8,16,⋯ ⟩a=\langle 1,2,4,8,16,\cdots\rangle 的生成函数是 ∑n≥02nxn\sum_{n\ge 0}2^nx^n.
  4. 序列 a=⟨1,3,5,7,9,⋯ ⟩a=\langle 1,3,5,7,9,\cdots\rangle 的生成函数是 ∑n≥0(2n+1)xn\sum_{n\ge 0}(2n+1)x^n.

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

基本运算

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

F(x)±G(x)=∑n(an±bn)xnF(x)\pm G(x)=\sum_n (a_n\pm b_n)x^n

因此 F(x)±G(x)F(x)\pm G(x) 是序列 ⟨an±bn⟩\langle a_n\pm b_n\rangle 的普通生成函数.

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

F(x)G(x)=∑nxn∑i=0naibn−iF(x)G(x)=\sum_n x^n \sum_{i=0}^na_ib_{n-i}

因此 F(x)G(x)F(x)G(x) 是序列 ⟨∑i=0naibn−i⟩\langle \sum_{i=0}^n a_ib_{n-i} \rangle 的普通生成函数.

封闭形式

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

例如 ⟨1,1,1,⋯ ⟩\langle 1,1,1,\cdots\rangle 的普通生成函数 F(x)=∑n≥0xnF(x)=\sum_{n\ge 0}x^n,我们可以发现

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

那么解这个方程得到

F(x)=11−xF(x)=\frac{1}{1-x}

这就是 ∑n≥0xn\sum_{n\ge 0}x^n 的封闭形式.

考虑等比数列 ⟨1,p,p2,p3,p4,⋯ ⟩\langle 1,p,p^2,p^3,p^4,\cdots\rangle 的生成函数 F(x)=∑n≥0pnxnF(x)=\sum_{n\ge 0}p^nx^n,有

F(x)px+1=F(x)F(x)=11−px\begin{aligned}F(x)px+1 &=F(x)\\F(x) &=\frac{1}{1-px}\end{aligned}

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

小练习

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

  1. a=⟨0,1,1,1,1,⋯ ⟩a=\langle 0,1,1,1,1,\cdots\rangle.
  2. a=⟨1,0,1,0,1,⋯ ⟩a=\langle 1,0,1,0,1,\cdots \rangle.
  3. a=⟨1,2,3,4,⋯ ⟩a=\langle 1,2,3,4,\cdots \rangle.
  4. an=(mn)a_n=\binom{m}{n}(mm 是常数,n≥0n\ge 0).
  5. an=(m+nn)a_n=\binom{m+n}{n}(mm 是常数,n≥0n\ge 0).
答案

第一个:

F(x)=∑n≥1xn=x1−xF(x)=\sum_{n\ge 1}x^n=\dfrac{x}{1-x}

第二个:

F(x)=∑n≥0x2n=∑n≥0(x2)n=11−x2\begin{aligned} F(x)&=\sum_{n\ge 0}x^{2n}\\ &=\sum_{n\ge 0}(x^2)^{n}\\ &=\frac{1}{1-x^2} \end{aligned}

第三个(求导):

F(x)=∑n≥0(n+1)xn=∑n≥1nxn−1=∑n≥0(xn)′=(11−x)′=1(1−x)2\begin{aligned}F(x)&=\sum_{n\ge 0}(n+1)x^n\\&=\sum_{n\ge 1}nx^{n-1}\\&=\sum_{n\ge 0}(x^n)'\\&=\left(\frac{1}{1-x}\right)'\\&=\frac{1}{(1-x)^2}\end{aligned}

第四个(二项式定理):

F(x)=∑n≥0(mn)xn=(1+x)mF(x)=\sum_{n\ge 0}\binom{m}{n}x^n=(1+x)^m

第五个:

F(x)=∑n≥0(m+nn)xn=1(1−x)m+1F(x)=\sum_{n\ge 0}\binom{m+n}{n}x^n=\frac{1}{(1-x)^{m+1}}

可以使用归纳法证明.

首先当 m=0m=0 时,有 F(x)=11−xF(x)=\dfrac{1}{1-x}.

而当 m>0m>0 时,有

1(1−x)m+1=1(1−x)m11−x=(∑n≥0(m+n−1n)xn)(∑n≥0xn)=∑n≥0xn∑i=0n(m+i−1i)=∑n≥0(m+nn)xn\begin{aligned} \frac{1}{(1-x)^{m+1}} &=\frac{1}{(1-x)^m}\frac{1}{1-x}\\ &=\left(\sum_{n\ge 0}\binom{m+n-1}{n}x^n \right)\left(\sum_{n\ge 0}x^n \right)\\ &=\sum_{n\ge 0} x^n\sum_{i=0}^n \binom{m+i-1}{i}\\ &=\sum_{n\ge 0}\binom{m+n}{n}x^n \end{aligned}

斐波那契数列的生成函数

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

斐波那契数列定义为 a0=0,a1=1,an=an−1+an−2  (n>1)a_0=0,a_1=1,a_n=a_{n-1}+a_{n-2}\;(n>1).设它的普通生成函数是 F(x)F(x),那么根据它的递推式,我们可以类似地列出关于 F(x)F(x) 的方程:

F(x)=xF(x)+x2F(x)−a0x+a1x+a0F(x)=xF(x)+x^2F(x)-a_0x+a_1x+a_0

那么解得

F(x)=x1−x−x2F(x)=\frac{x}{1-x-x^2}

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

展开方式一

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

F(x)=x1−(x+x2)=x∑k=0∞(x+x2)k=x∑k=0∞∑i=0k(ki)xk−i(x2)i=∑k=0∞∑i=0k(ki)xk+i+1=∑n=1∞∑i=0⌊(n−1)/2⌋(n−i−1i)xn.\begin{aligned} F(x) &= \dfrac{x}{1-(x+x^2)} \\ &= x\sum_{k=0}^{\infty}(x+x^2)^k \\ &= x\sum_{k=0}^{\infty}\sum_{i=0}^k\binom{k}{i}x^{k-i}(x^2)^i \\ &= \sum_{k=0}^{\infty}\sum_{i=0}^k\binom{k}{i}x^{k+i+1} \\ &= \sum_{n=1}^{\infty}\sum_{i=0}^{\lfloor(n-1)/2\rfloor}\binom{n-i-1}{i}x^n. \end{aligned}

最后一步中,令 n=k+i+1n=k+i+1 并更换求和顺序.由此,可以得到通项公式:

an=∑i=0⌊(n−1)/2⌋(n−i−1i).a_n = \sum_{i=0}^{\lfloor(n-1)/2\rfloor}\binom{n-i-1}{i}.

这并不是我们熟知的有关黄金分割比的形式.

展开方式二

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

A1−ax+B1−bx=x1−x−x2\frac{A}{1-ax}+\frac{B}{1-bx}= \frac{x}{1-x-x^2}

通分得到

A−Abx+B−aBx(1−ax)(1−bx)=x1−x−x2\frac{A-Abx+B-aBx}{(1-ax)(1-bx)} = \frac{x}{1-x-x^2}

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

{A+B=0−Ab−aB=1a+b=1ab=−1\begin{cases} A+B=0\\ -Ab-aB=1\\ a+b=1\\ ab=-1 \end{cases}

解得

{A=15B=−15a=1+52b=1−52\begin{cases} A=\frac{1}{\sqrt{5}}\\ B=-\frac{1}{\sqrt{5}}\\ a=\frac{1+\sqrt{5}}{2}\\ b=\frac{1-\sqrt{5}}{2} \end{cases}

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

x1−x−x2=∑n≥0xn15((1+52)n−(1−52)n)\frac{x}{1-x-x^2}=\sum_{n\ge 0}x^n \frac{1}{\sqrt{5}}\left( \left(\frac{1+\sqrt{5}}{2}\right)^n-\left(\frac{1-\sqrt{5}}{2}\right)^n \right)

这也被称为斐波那契数列的另一个封闭形式(x1−x−x2\frac{x}{1-x-x^2} 是一个封闭形式).

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

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

G(x)=1(1−x)(1−2x)2G(x)=\frac{1}{(1-x)(1-2x)^2}

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

G(x)=c01−x+c11−2x+c2(1−2x)2G(x)=\frac{c_0}{1-x}+\frac{c_1}{1-2x}+\frac{c_2}{(1-2x)^2}

解得

{c0=1c1=−2c2=2\begin{cases} c_0&=1\\ c_1&=-2\\ c_2&=2 \end{cases}

那么

[xn]G(x)=1−2n+1+(n+1)⋅2n+1[x^n]G(x)=1-2^{n+1}+(n+1)\cdot 2^{n+1}

牛顿二项式定理

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

(rk)=rk‾k!(r∈C,k∈N)\binom{r}{k}=\frac{r^{\underline{k}}}{k!}\quad(r\in\mathbf{C},k\in\mathbf{N})

注意 rr 的范围是复数域.在这种情况下.对于 α∈C\alpha\in\mathbf{C},有

(1+x)α=∑n≥0(αn)xn(1+x)^{\alpha}=\sum_{n\ge 0}\binom{\alpha}{n}x^n

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

卡特兰数的生成函数

参考 Catalan 数形式的代数推演.

应用

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

食物

食物

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

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

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

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

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

  1. ∑n≥0x2n=11−x2\displaystyle\sum_{n\ge 0}x^{2n}=\dfrac{1}{1-x^2}.
  2. 1+x1+x.
  3. 1+x+x2=1−x31−x1+x+x^2=\dfrac{1-x^3}{1-x}.
  4. x1−x2\dfrac{x}{1-x^2}.
  5. ∑n≥0x4n=11−x4\displaystyle \sum_{n\ge 0}x^{4n}=\dfrac{1}{1-x^4}.
  6. 1+x+x2+x3=1−x41−x1+x+x^2+x^3=\dfrac{1-x^4}{1-x}.
  7. 1+x1+x.
  8. 11−x3\dfrac{1}{1-x^3}.

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

F(x)=(1+x)(1−x3)x(1−x4)(1+x)(1−x2)(1−x)(1−x2)(1−x4)(1−x)(1−x3)=x(1−x)4F(x)=\frac{(1+x)(1-x^3)x(1-x^4)(1+x)}{(1-x^2)(1-x)(1-x^2)(1-x^4)(1-x)(1-x^3)} =\frac{x}{(1-x)^4}

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

F(x)=∑n≥1(n+2n−1)xnF(x)=\sum_{n\ge 1}\binom{n+2}{n-1}x^n

因此答案就是 (n+2n−1)=(n+23)\dbinom{n+2}{n-1}=\dbinom{n+2}{3}.

Sweet

「CEOI2004」Sweet

有 nn 堆糖果.不同的堆里糖果的种类不同(即同一个堆里的糖果种类是相同的,不同的堆里的糖果的种类是不同的).第 ii 个堆里有 mim_i 个糖果.现在要吃掉至少 aa 个糖果,但不超过 bb 个.求有多少种方案.

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

n≤10,0≤a≤b≤107,mi≤106n\le 10,0\le a\le b\le 10^7,m_i\le 10^6.

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

Fi(x)=∑j=0mixj=1−xmi+11−xF_i(x)=\sum_{j=0}^{m_i}x^j=\frac{1-x^{m_i+1}}{1-x}

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

G(x)=∏i=1nFi(x)=(1−x)−n∏i=1n(1−xmi+1)G(x)=\prod_{i=1}^n F_i(x)=(1-x)^{-n}\prod_{i=1}^n(1-x^{m_i+1})

现在我们要求的是 ∑i=ab[xi]G(x)\sum_{i=a}^b[x^i]G(x).

由于 n≤10n\le 10,因此我们可以暴力展开 ∏i=1n(1−xmi+1)\prod_{i=1}^n(1-x^{m_i+1})(最多只有 2n2^n 项).

然后对 (1−x)−n(1-x)^{-n} 使用牛顿二项式定理:

(1−x)−n=∑i≥0(−ni)(−x)i=∑i≥0(n−1+ii)xi\begin{aligned} (1-x)^{-n} &=\sum_{i\ge 0}\binom{-n}{i}(-x)^i\\ &=\sum_{i\ge 0}\binom{n-1+i}{i}x^i \end{aligned}

我们枚举 ∏i=1n(1−xmi+1)\prod_{i=1}^n(1-x^{m_i+1}) 中 xkx^k 项的系数,假设为 ckc_k.那么它和 (1−x)−n(1-x)^{-n} 相乘后,对答案的贡献就是

ck∑i=a−kb−k(n−1+ii)=ck((n+b−kb−k)−(n+a−k−1a−k−1))c_k\sum_{i=a-k}^{b-k}\binom{n-1+i}{i}=c_k\left( \binom{n+b-k}{b-k}- \binom{n+a-k-1}{a-k-1} \right)

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

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

本文内容来自 OI Wiki《普通生成函数》;作者与修订历史见原文。AIOJ 对排版、站内链接和资源路径做了格式适配。

内容依 CC BY-SA 4.0 与 SATA 许可共享;附加条款以原文声明为准。感谢 OI Wiki 作者与贡献者;请按 SATA 约定前往 OI Wiki 仓库 Star 支持。