生成函数:从入门到出门

本博客在看完《多项式:从入门到全家桶》《组合数学:从入门到被入门》后食用更佳。

生成函数简介

省流:

普通生成函数: f(x)=i0aixi

指数生成函数: f(x)=i0aixii!

狄利克雷函数生成函数: f(x)=i0aiix

普通生成函数(重点)

又记作OGF(Ordinary Generating Function)。

本章中记 ax 为序列 a 的普通生成函数 。

定义式:ax=i0aixi

并且,如果 f(x) 为一个函数,我们记 fn 为其多项式表达中 xn 的系数,反之亦然,即 f=fx

基本运算

加减法很显然。

ax+bx=ax+bxaxbx=axbx

乘法仔细想一想其实也不难,由基础的乘法分配律可知:

axbx=i=0xaibxi

原本需要 O(n2) 的时间计算,使用FFT或NTT即可加速到 O(nlogn),有关多项式快速运算的内容请见《多项式:从入门到全家桶》

封闭形式

举个栗子。

假设我们现在有一个函数叫做 f(x)=1,1,1,,1

我们发现这个式子有一个性质:

f(x)=xf(x)+1

于是 f(x)=1x1,这就是 f(x) 的封闭形式。

一般来说,把一个式子写成它的封闭形式能够便于推式子。

比如让你求 f(x)(x22x+1) ,我们用定义式可能要推很久,但你用封闭形式就能马上推出上式 =x1

建议大家多练习一下推封闭形式。

多项式的四则运算,求导,积分等所有运算对封闭形式同样适用。

小练习:请求出以下几个式子的生成函数的封闭形式。

  1. 0,1,1,1,1,
  2. 1,0,1,0,1,
  3. 1,2,3,4,5,
  4. (mx)
  5. (m+xt)
答案
  1. f(x)=x1x
  2. f(x)=11x2
  3. f(x)=xf(x)+n0xn,f(x)=1(1x)2
    另解:f(x)=n1nxn1=(n1xn)=(11x)=1(1x)2
  4. (二项式定理)f(x)=(1+x)m
  5. f(x)=n0(m+nn)xn=1(1x)m+1

可使用归纳法进行证明。

m=0 时显然成立。

m>0 时:

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

例:斐波那契数列的生成函数

我们定义 a0=1,a1=a,ai=ai1+ai2(i2),那我们该怎样求出 at 呢?

一个显然的方法就是利用 ai=ai1+ai2 这一性质。

我们知道多项式乘 x 相当于把这个多项式向高次项移一位。

于是我们可以得到这个方程:

f(x)=xf(x)+x2f(x)+a1x+a0x+a0=xf(x)+x2f(x)+x

解得 f(x)=11xx2

于是我们接下来的问题就是如何把这个式子展开。

展开方式1

我们将 x+x2 视作一个整体。则有:

f(x)=x1(x2+x)=xn0(x2+x)n=xn0i=0n(ni)(x2)ixni)=xn0i=0n(ni)xn+i)=n1xni=0n1(n1ii)=i=0x1(x1ii)

我们发现我们成功地解决了通项公式,但这是一个组合数求和的形式,并不是我们熟知的黄金分割比。

所以这个方法不行。

展开方式2

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

A1ax+B1bx=x1xx2

通分后得到:

AAbx+BBaxabx2(a+b)x+1=x1xx2

则有:

{A+B=0Ab+Ba=1a+b=1ab=1

它的一组解为:

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

于是

at=x1xx2=15(111+52x11152x)=15n0xn((1+52)n(152)n)=(1+52)x(152)x

这有的时候也被称为斐波那契数列的第二个封闭形式。(第一个封闭形式:x1xx2

其实,我们求 p(x)q(x) 的时候基本上都会用这种办法(即待定系数法)求出它的展开式。

一般来说,对于 q(x) 比较容易因式分解时,我们就可以直接把几个分式的分母表示成它的几个因式,然后列方程求解。

如果有相同因式(即次数 2),就设其中一个分式为这个因式的高次方。

比如 1(1x)(12x)2 就可以写成 A1x+B12x+C(12x)2 的形式。

应用

生成函数主要应用于各种计数问题,其目的是用简单的式子把一些复杂的转移表示出来。

下面举几个例子:

推通项公式

这个不说了,前面的斐波那契数列的例子已经说过了。

背包问题

传统的解决背包问题的方法就是dp,但这种办法在有些比较复杂的题上就行不通。

其实,如果你要求价值和刚好为 n 的答案(一般是方案数),你可以把这个答案写成生成函数的形式。

就拿方案数来说,你对每种不同的限制计算出它的生成函数,并把它们乘起来,最终式子的第 n 项就是答案。

以某道题为例:

在许多不同种类的食物中选出 n 个,n10500,求方案数,对 10007 取模,每种食物的限制如下:

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

我们设 ai,j 表示第 i 种食物选 j 个的方案数,则 [xn](iai,t) 就是答案。

考虑卷积的定义,值为 1 ,下标和为 n 的几项相乘就代表分别选择那几项是一种符合条件的方案,而这对 xn 的系数贡献为 1

建议此处读者自行推导一下这几种食物的生成函数,争取自己把式子推出来。

答案
  1. n0x2n=11x2=1(1x)(1+x)
  2. 1+x
  3. 1+x+x2
  4. n0x2n+1=x1x2=x(1x)(1+x)
  5. n0x4n=11x4=1(1x)(1+x)(1+x2)
  6. 1+x+x2+x3=(x2+1)(x+1)
  7. 1+x
  8. n0x3n=11x3=1(1x)(1+x+x2)

把上面所有式子乘起来可得:

ans=x(1x)4

由之前的第五条小练习,我们知道这就是 n1xn(n+1n2)

因此答案就是 (n+1n2)=(n+13)

代码略。

推算式

有的时候,有些题会让你求恰好等于 n 的方案数、在某个区间内的方案数,或者对于每个数都求一遍。

这种题有的时候就可以用生成函数的形式推。(尤其是有包含组合数的式子)

结合上某些多项式高科技,一般可以比传统方法快很多。

指数生成函数

又记作EGF(Exponential Generating Function)。

本章中记 {ax} 为序列 a 的指数生成函数。

定义式:{ax}=i0aixii!

基本运算

加减法也很显然。

{ax}+{bx}={ax+bx}{ax}{bx}={axbx}

乘法可能会稍稍难一些,但经过一些推导实际上也不难。

{ax}{bx}={i=0x(xi)aibxi}

指数生成函数与普通生成函数互转的公式:

{ax}=axx!ax={axx!}

另外,由于指数生成函数的定义,其导数和积分很好求。

{ax}={ax+1}{ax}={ax1}(a1=0)

封闭形式

疯毙形式(确信)

一般来说,指数生成函数的多项式的封闭形式和泰勒展开有关。(因为泰勒展开主要就是 i0aixii! 的形式)

我们考虑 f(x)={1,1,1,1,} ,有两种方式求出它的封闭形式:

  1. 定义式,f(x)=i0xii!=exex 的泰勒展开)
  2. 考虑 f(x)=f(x) ,于是 f(x)=ex 。(这个方法不够严谨,慎用)

类似的,等比数列的生成函数 f(x)={1,p,p2,p3,} 的封闭形式就是 epx

排列、圆排列与多项式 exp

长度为 n 的排列数(n!)的EGF是:

f(x)={x!}=i0i!xii!=1,1,1=11x

圆排列数的定义是旋转后方案等价的排列数。

长度为 n 的圆排列数((n1)!)的EGF是:

g(x)={(x1)!}=i1(i1)!xii!=1i=ln(1x)=ln11x

于是我们就有 f(x)=expg(x)

但这只是数学上的推导,我们还需要一些直观理解。

我们引入一个概念,叫做置换环

对于一个排列 p ,我们对于每个 ipi 连边,置换环就是这张图中所有连成的环。(包括自环)

并且对于两个排列,当且仅当它们所有的置换环相同时,这两个排列才相同。

于是对于长度为 n 的排列数,我们可以按照以下这个步骤进行计算:

  1. 1,2,,n 分成若干个集合。
  2. 对于每个集合,构造一个置换环。

这样得出的方案数就是长度为 n 的排列数。

更进一步,我们发现对于一个集合,构造置换环的方案数就是这个集合的圆排列数。

所以,长度为 n 的排列数就是将 1,2,,n 划分成若干集合,每一部分做圆排列数的方案数。

因此,多项式 exp 的直观理解就是:

f(x)=expg(x) ,则 fn 代表将 1,2,,n 分成若干集合,每一集合 S 的方案数为 g|S| 时总共的方案数。

类似的,我们举一些例子:

  • 如果 n带标号点的生成树个数的EGF为 f(x) ,则 n带标号点的生成森林个数的EGF为 expf(x)

  • 如果 n带标号点的无向连通图个数的EGF为 f(x) ,则 n带标号点的无向图个数的EGF为 expf(x)

因此,只要这两个中求出任意一个,则可利用多项式 lnexp 求出另一个。

应用

各种排列

举个例子:求错排数的EGF。

我们都知道错排数就是 i,ipi 的方案数,也就是不存在长度为 1 的置换环的个数。

而后者的EGF为 i2xii=i1xiix=ln(1x)x

于是错排数的EGF为 exp(ln(1x)x)

expln 的组合意义

前面说过,不讲。

OGF推出来的式子有组合数

可转化为EGF进行求解。

例:分别求出有 i(1i105) 个节点的竞赛图(一个完全图,但是每条边定向)中至少有一条哈密顿回路的方案数。

不妨设这个答案数组为 gi ,有 i 个节点的竞赛图个数为 fi=2(i2)=2i(i1)2
由于一张竞赛图缩点就变成了一个链状DAG(有向无环图),因此我们枚举最后一个连通块内有多少点:

fn=i=1n(ni)gifni

这个式子和分治FFT很像,但是多了一个组合数。

于是我们设 fi=fii!gi=gii!

于是就有

fn=i=1ngifni

化为分治FFT或多项式求逆即可。

顺便复习一下上面那个式子如何多项式求逆:

由于 f0=1 (计算方案时可定义),则原式可化为:

f(x)=f(x)g(x)+1

即:f(x)=11g(x)g(x)=11f(x)

狄利克雷生成函数

以后再说。

本章主要记载了推式子过程中容易用到的知识。

二项式反演

《组合数学:从入门到被入门》

牛顿二项式定理

我们都知道,著名的二项式定理是指:

(1+x)n=i=0n(ni)xi

更进一步,我们把组合数的定义域拓展到复数上:

(rk)=rkk!

其中 ab=a(a1)(a2)(ab+1)

于是我们就有了:

(1+x)n=i0(ni)xi

虽然这个定理不常用,但有的时候推式子还是用得上的。

posted @   SqrtSecond  阅读(935)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
点击右上角即可分享
微信分享提示