关于生成函数

基础

普通生成函数

对于数列$a_i$,它的普通生成函数($\text{OGF}$)为$A(x)=\sum a_ix^i$

这个$x^i$刚开始并没有实际意义,即为形式幂级数,实际这个$i$甚至可以不是一个整数,如$\text{FWT}$中的指数为集合幂指数

普通生成函数常用于解决无序的组合计数问题,如背包问题

常见背包的生成函数

我们让$x^i$项表示选择了$i$个物品,则可以构造生成函数

一个01背包,每一个物品的生成函数为$A(x)=x+1$,其中$x$项表示多选了一个,1项表示空着不选

同理,对于一个有限背包,每个物品上限$m_i$,则$A_i(x)=\sum_{j=0}^{m_i} x^j$

一个完全背包的生成函数为$\begin{aligned} A(x)=\sum_{i=0}^{\infty} x^i=\frac{1-x^{\infty} } {1-x}=\frac{1} {1-x}\end{aligned} $(因为我们所求的答案是前若干项,无穷项没有意义)

那么多个物品的组合就可以通过这些生成函数相乘来轻松表示,因此也容易被多项式的快速运算优化

用生成函数描述递推关系

一个最简单的例子,设斐波那契数列的普通生成函数为$F(x)$

我们知道$F_i=F_{i-1}+F_{i-2},F_0=0,F_1=1$

则可以用生成函数表示斐波那契数列的递推关系$F(x)=x F(x)+x^2 F(x)+x$

其中$xF(x)$对应递推式的$F_{i-1}$,$x^2F(x)$对应递推式的$F_{i-2}$,$x$对应$F_1$的值

类似的问题还包括数列的线性递推,即$a_i=\sum b_ja_{i-j}$,但是这个求解比较复杂。。。

基于概率期望的生成函数

取自 集训队论文 2018 - 1 浅谈生成函数在掷骰子问题上的应用长沙市长郡中学杨懋龙

对于随机非负离散变量$x$,令它的概率生成函数是$F(z)=\begin{aligned}\sum_{i=0}^{\infty}P(x=i)z^i\end{aligned}$,则可以看到这里的指数代表$x$的值

$x$的值不一定能够相加,但是利用这个生成函数,可以快速表达期望,方差等,具体见下式

1.$F(1)=\begin{aligned}\sum_{i=0}^{\infty}P(x=i)=1\end{aligned}$

2.$F'(1)=\begin{aligned}\sum_{i=0}^{\infty}P(x=i)\cdot i=E(x)\end{aligned}$

3.$E(x^{\underline{k} })=F^{(k)}(1)$ ($x$的$k$阶下降幂,($k$)表示$k$阶导数)

4.$x$的方差$=\begin{aligned}\sum_{i=0}^{\infty}P(x=i)\cdot (i-E(x))^2\end{aligned}=\begin{aligned}\sum_{i=0}^{\infty}P(x=i)\cdot i^2-2P(x=i)\cdot i\cdot E(x)+P(x=i)\cdot E^2(x)\end{aligned}$

$=E(x^2)-2E^2(x)+E^2(x)=E(x^2)-E^2(x)=E(x^{\underline{2} })+E(x)-E^2(x)=F’’(1)+F’(1)-(F’(1))^2$

可以作为导数在生成函数推导中应用的一个例子

指数生成函数

对于数列$a_i$,它的指数生成函数($\text{EGF}$)为$\begin{aligned} A(x)=\sum \frac{a_ix^i} {i!}\end{aligned} $

指数型生成函数是处理有序排列问题的一大利器,因此,指数上的$i$通常表示个数

为什么$\frac{1} {i!}$可以简化排列问题,可以参见这样的一个例子

用若干类物品排成一个排列,每一类有$m_i$个,则不同的排列个数为 $\begin{aligned} \frac{(\sum m_i)!} {\prod m_i!}\end{aligned} $

这个式子的意义就是: 假设先随便排列,由于每一类相同,因此类之内的排列都要除掉

可以看到,$\frac{1} {i!}$描述的就是类内的排列,因此最后求得答案项还要乘上$n!$

如果一类物品任意个数加入排列,则其指数生成函数为$\begin{aligned} A(x)=\sum_{i=0}^{\infty}\frac{x^i} {i!}=e^x\end{aligned} $

根据$e^{-x}=\sum_i \frac{(-x)^i} {i!}$,还能得到:

限制为偶数个的指数生成函数$\begin{aligned} A(x)=\sum_{2|i}^{\infty}\frac{x^i} {i!}=\frac{e^x+e^{-x} } {2}\end{aligned} $

限制为奇数个的指数生成函数$\begin{aligned} A(x)=\sum_{2|i}^{\infty}\frac{x^i} {i!}=\frac{e^x-e^{-x} } {2}\end{aligned} $

限制为$n$的倍数个,较为复杂,需要用到单位根反演

$e^{x}$在排列问题叠加上的应用

若有一类等价排列子问题,其指数型生成函数为$F(x)$,则任意叠加其得到的排列问题指数型生成函数为

$\begin{aligned} \sum_{i=0}^{\infty} \frac{F^i(x)} {i!}=e^{F(x)}\end{aligned} $,其中$\frac{1} {i!}$表示除去子问题之间等价

更多常用技巧

1.分治NTT解决多个多项式卷积问题

2.CDQ分治NTT解决有序递推问题

3.推导生成函数的关系

3-1.树的递归关系

问题: 计算合法树的数量,如树上染色问题等

这一类问题可以表示为 一种递归关系,即 枚举根的状态 加上根的儿子对应的生成函数

例子 [Codeforces Round #250]小朋友和二叉树

设一个点的生成函数为$G$,整棵数的生成函数为$F$,其中幂指数代表权值和,则$G$是我们已知的,且有关系

$F=G\cdot F^2+1$,其中$F^2$表示枚举两个子树的状态,$G$表示枚举根的状态,$+1$表示空树

类似这样的问题还有 烷基计数加强版加强版 这个方程要用到牛顿迭代求解

3-2.

4.集合幂指数在处理01状态上的应用

如果用整数指数形式表示的生成函数解决01状态上的or,and,xor操作

我们通常需要把这个过程转化为对$0,1$个数来做

但是这一类的问题,通常可以用集合幂指数轻松表示,前提是你了解$\text{FWT}$卷积三种类型的本质过程

例题 ZJOI 2019开关