生成函数学习笔记
配套练习总地址 后面将只会写出题号(如:CF666D
),题解+代码都可以在这里找到。
学习博文是 多项式计数杂谈 ,结合了一些别的东西和自己的理解。
前置
微积分常用公式
求导线性性 :
基本求导法则 :
链式法则 :\(\dfrac{d}{dx}\dfrac{dx}{dz}=\dfrac{d}{dz}\)
复合函数求导 :(使用链式法则)
洛必达法则 :
如果 \(\lim\limits_{x\to x_0}F(x)=0\) ,\(\lim\limits_{x\to x_0}G(x)=0\) ,且 \(G'(x)\neq 0\) ,那么有
常见不定极限的形式有 \(\dfrac{\infin}{\infin},\infin-\infin,0*\infin\) ,经过一些变化都能变成 \(\dfrac{0}{0}\) 形式。
泰勒展开及牛顿迭代 :见 多项式基础学习笔记(1) 相关部分。
有限微积分
可以参考 《具体数学》
2.6 有限微积分和无限微积分
.
无限微积分基于由
定义的微分算子 \(D\) ,逆运算为 \(\int\) .
有基本规则(就是求导那个最简单的式子):\(D(x^m)=mx^{m-1}\) .
有限微积分基于由
定义的差分算子 \(\Delta\) ,逆运算为 \(\sum\) .
对于 \(\Delta\) ,下降幂有类似的优美规则:\(\Delta(x^{\underline m})=mx^{\underline{m-1}}\) ,是基本的阶乘结果。
对下降幂求和,类似 \(\int x^k=\dfrac{x^{k+1}}{k+1}\) ,有 \(\displaystyle\sum\limits_{i=0}^{n-1}i^{\underline k}=\dfrac{n^{\underline{k+1}}}{k+1}\) 。特别地,当 \(k=-1\) 时,有 \(\sum\limits_{i=0}^{n-1}i^{\underline{-1}}=\sum\limits_{i=1}^n\dfrac 1i\) 。
定义移位算子 \(Ef(x)=f(x+1)\) ,有分部求和法则:\(\displaystyle \sum u\Delta v=uv-\sum Ev\Delta u\) .
阶乘幂的性质
阶乘幂就是上升幂和下降幂的统称。
下降幂多项式:《具体数学》5.3 处理的技巧 - 技巧2:高阶差分
里面提到,能将通常幂表示成下降幂的和式。下降幂的求和是相当容易的(见上面的式子)。
二项式反演
这里简单给出二项式反演的两个形式。
(听说下面那种更常用……可能我做题比较少)
二项式反演+下降幂的两道练习题:
P4921
:二项式反演+简单容斥
CF755G
:二项式反演+组合+化下降幂
生成函数
幂级数和封闭形式
\(F(x)=\sum\limits_{i=0}^{\infin}F[i]x^i\) 被称为 幂级数 ,系数 \(F[i]\) 可以看做一个数列。那么幂级数也可以用如下方式得到:对于一个数列,将每个数附上 \(x\) 的幂,得到一个幂级数。例如,数列 \(\left<1,1,\cdots\right>\) 所得到的幂级数是 \(F(x)=\sum\limits_{i=0}^{\infin}x^i\) ,观察 \(F(x)\) 和 \(xF(x)\) ,有 \(F(x)=xF(x)+1\) ,于是有:\(F(x)=\dfrac{1}{1-x}\) ,这就是它的生成函数。
这里可能会产生一个问题:\(F(x)\) 收敛当且仅当 \(|x|<1\) ,但 幂级数收敛只是构造的条件 ,而非自然推导的产物。
一种理解是 多项式基础学习笔记(1) 开头提到的界的概念, \(\displaystyle\sum\limits_{i=0}^{\infin}x^i\bmod x^n=\sum\limits_{i=0}^{n-1}x^i=\dfrac{1-x^n}{1-x}\) 有界。
另一种可以参看 rqy 的博文:浅谈 OI 中常用的一些生成函数运算的合法与正确性 .
类似 \(\dfrac{1-x^n}{1-x}\) 这样,相对和式或递归式更加简洁的式子,称为 “封闭形式” 。一些推导封闭形式的方法可以自行查阅《具体数学》,这里仅仅列举将和式转化为封闭形式的常见方式:
- 归纳法
- 扰动(就是将某一项(通常是头尾)剥离或加入进去,从而得到便于计算的式子),并利用交换求和次序等一些推式子常用技巧,或是将式子一般化(复杂化),然后再简化
- 成套方法(对于递推式建立的一般方法)
- 用积分替换和式,有限微积分
- 生成函数
\(\left<1,a,a^2,a^3,\cdots \right>\to F(x)=axF(x)+1\) ,所以 \(F(x)=\dfrac{1}{1-ax}\) 。类似这样的推导是很常见的手段之一:将递推式适当乘上 \(x\) 的幂次然后错位,用 \(F(x)\) 表示它自己,进而得到封闭形式。
下面将给出一些数列的推导。
Eg 1. 斐波那契数列
令 \(F[i]\) 表示数列第 \(i\) 项,\(F[0]=0,F[1]=1\) .
首先,写成生成函数的形式:\(F(x)=\sum\limits_{i=0}^{\infin}F[i]x^i\) 。然后,利用上面的错位技巧,结合斐波那契数列的递推式和前两项有关,不难想到用 \(xF(x),x^2F(x)\) 来推导:
由于 \(F[i]=F[i-1]+F[i-2]\) ,所以相加得到:
于是就有
这个封闭形式能求出斐波那契的通项公式 虽然没那么好看 :
令 \(x_1,x_2\) 为 \(1-x-x^2\) 的两实根,有
发现对 \(\dfrac{1}{x-x_1}\) 的分母取相反数,可以得到一个类似 \(\dfrac{1}{1-x}\) 的形式(别忘了,我们要求通项!所以必须要逆用封闭形式),那么考虑将它转化成这个形式
直接逆用封闭形式就能得到
提出 \([x^n]\) ,然后将 \(x_1,x_2\) 实值带入即可。
Eg 2. 特征方程(解二阶递推式)
一阶的成套方法可以在《具体数学》第二章中找到。
求解 \(F[n]=a*F[n-1]+b*F[n-2]\) 的通项公式,其中 \(F[0],F[1]\) 已知。
不妨设 \(F\) 是一个公比为 \(q\) 的等比数列,将所有 \(F[]\) 换成 \(F[n-2]\) 并用 \(n\to n-2\) 得
设得到的两根为 \(q_0,q_1\) ,那么 \(F[n]=x_0q_0^n+x_1q_1^n\) 也必然满足递推公式,所以只需要用 \(F[0],F[1]\) 求出 \(x_0,x_1\) 即可。
Eg 3. 常系数齐次线性递推(获取封闭形式)
设对于数列 \(F\) 和递推系数 \(C\) ,当 \(n\ge k\) 时有 \(C[0]=1\) ,\(\displaystyle \sum\limits_{i=0}^kC[i]F[n-i]=0\) ,那么称 \(F\) 满足 \(k\) 阶线性常系数递推关系。令 \(F(x)\) 为 \(F[n]\) 的生成函数,构造
提出上式的 \([x^n]\) 系数,得到的 \([n\ge k]C[t]F[n-t]\) 就符合定义式,所以 \(\displaystyle\sum_{t=0}^kF_t(x)=0\) ,即
左式是 \(C\) 的生成函数,右边次数小于 \(k\) ,设为 \(P(x)\) ,得到 \(C(x)F(x)=P(x)\) ,即 \(F(x)=\dfrac{P(x)}{C(x)}\) 。
这样就得到了 \(F\) 的生成函数。
\(\huge\color{red}具体操作咕咕咕,待填坑\)
Eg 4. 卡塔兰数
\(C[0]=1\) ,\(C[n]\) 表示 \(n\) 对括号的合法序列个数。有 \(C[n+1]=\sum_{i=0}^nC[i]C[n-i]\) 。
令其自卷,得到
而 \(C[k+1]\) 的幂级数是 \(\dfrac{C(x)-1}{x}\) (相当于是整个 \(C[k]\) 序列平移到了 \(C[k+1]\) 序列),所以有
而生成函数有重要假设是其收敛,那么只需要验证 \(\lim_{x\to 0}C(x)=C[0]=1\) 即可,发现必须取负号。
由广义二项式定理,有 \(\displaystyle\sqrt{1-4x}=\sum\limits_{i=0}^{\infin}\binom{1/2}{i}(-4x)^i\) ,所以可以得到系数
另一种方式是用广义二项式级数得到:(参见《具体数学》5.4 生成函数
)
系数即为 \(\displaystyle \binom{2n}{n}\dfrac{1}{n+1}\) .
生成函数组合计数初步
组合对象
一般指满足某一性质的图、串等对象组成的集合 \(A\) ,每个元素 \(a\in A\) 被定义了一个函数 \(siz(a)\) (如节点个数、串长),对于某个固定的 \(n\) ,记 \(siz(a)=n\) 的 \(a\) 的个数为 \(A[n]\) .
OGF
基本概述
普通生成函数 ordinary generating function
数列 \(F[n]\) 的 OGF
为 \(F(x)=\sum\limits_{i=0}F[i]x^i\) 。例如:
无标号对象的笛卡尔积
集合 \(A_1,A_2,\cdots,A_n\) 的笛卡尔积为 \(\{(a_1,\cdots ,a_n)||a_1\in A_1,a_2\in A_2,\cdots ,a_n\in A_n\}\) ,记为 \(A_1\times \cdots \times A_n\) ,也就是从每个集合中各取一个元素形成的有序多元组集合。
对于两个无标号组合对象 \(A,B\) ,令 \(D=A\times B\) ,且 \(D\) 中的每个元素 \(d\) 为二元组 \((a,b)\) ,\(a\in A,b\in B\) ,\(siz(d)=siz(a)+siz(b)\) ,于是有 \(D(x)=A(x)*B(x)\) .
其实就是一个类似背包的思想,\(A\) 里面拿一个,\(B\) 里面拿一个,拼成 \(D\) 里的那个。
Eg 骨牌问题
有若干种颜色互不相同的骨牌,其中长度为 \(i\) 的骨牌有 \(A[i]\) 种,每种可以无限使用,求不重叠铺满 \(n\) 个长度的方案数。
不难想到 \(A(x)^k\) 就是 \(k\) 个骨牌拼接的方案数(可以类比矩阵加速中,计算经过 \(k\) 条路之后的可达性的问题,更好理解),那么生成函数就是 \(\dfrac{1}{1-A(x)}\) ,求逆即可。
一个子问题就是斐波那契数,可以看做 \(\{1,2\}\) 的拼接序列。
另一个子问题:P4451
,骨牌+二次剩余+特征方程
实战演练
UVA12298
:背包+笛卡尔积
CF438E
:构造式子
CF917D
:树形DP+Prufer结论+组合意义
EGF
基本概述
指数型生成函数 exponential generating function
对于数列 \(F[n]\) ,其 EGF
为 \(F(x)=\sum\limits_{i=0}F[i]\dfrac{x^i}{i!}\) 。两个 EGF
的乘法如下:
常见 EGF
的例子:
有标号对象的笛卡尔积
两个有标号对象 \(a,b\) ,设其标号为 \(1\sim siz(a),1\sim siz(b)\) ,拼接得到 \(c\) 的方案数为 \(\displaystyle\binom{siz(a)+siz(b)}{siz(a)}\) ,也就是从 \(siz(a)+siz(b)\) 中选出 \(siz(a)\) 个给 \(a\) 中的元素,如果不能理解自行学习高中数学排列组合。
Eg 染色问题
rbg
三种颜色染色一个长度为 \(n\) 的纸条,使得颜色 r
b
的个数是偶数,求方案数。
我们可以分别求出单个染色的 EGF
然后再合并(也就是 EGF
卷积),而单个染色的 EGF
分别是 \(e^x,\dfrac{e^x+e^{-x}}{2}\) ,前一个是 \(\{1\cdots\}\) 的 EGF
,后一个用 \(\{1\cdots\}\) 及其符号交替形式不难得到。相乘就得到:
实战演练
HDU1521
\(n\) 种物品选出 \(m\) 的排列数,直接 EGF
卷积。
P5219
结论:\(n\) 点最大度数为 \(m\) 的树的个数为 \(G(n,m-1)-G(n,m-2)\) ,\(G(n,m)\) 为 \(\left(\sum\limits_{i=0}^m \dfrac{x^i}{i!}\right)^n\) 的第 \(n-2\) 项。
P5339
exp 的组合意义
\(\exp F(x)\) 的展开式为 \(\sum\limits_{i=0}\dfrac{F(x)^i}{i!}\) ,如果将 \(F(x)\) 看成单个元素的 EGF
,那么 \(\exp F(x)\) 就是这些元素组成的有标号集合。展开式的意义就是枚举元素个数并卷积拼接,由于元素无序所以要除以一个阶乘。这样就能解决一些集合计数问题。
置换计数
置换定义:有限集合到自身的双射。置换其实就是一系列环有标号生成的集合。
给出一个集合 \(S\) ,求环大小在 \(S\) 内的 \(1\sim n\) 元置换个数。
一个大小为 \(n\) 的环的排列总数为 \(n!\) ,因为环能旋转,所以等价类总数为 \((n-1)!\) 。
单个环的 EGF
为 \(\displaystyle\sum\limits_{i=1}[i\in S]\dfrac{(i-1)!x^i}{i!}\) ,然后 \(\exp\) 即可。
如果所有大小都可选, \(\displaystyle\sum_{i=1}\dfrac{(i-1)!x^i}{i!}=-\ln(1-x)\) ,\(\exp(-\ln(1-x))=\dfrac{1}{1-x}\) 。
实战演练
P4841
结论:\(n\) 点简单有标号无向连通图的方案数为 \(\ln G(x)\) ,\(G(n)=2^{\binom n2}\) .
P5162
重要结论
对于一类组合对象 \(A\) ,由 \(A\) 种元素组成的序列定义的一类组合对象 \(B\) ,其生成函数为
这个结论对 OGF
,EGF
均成立。
PGF
基本概述
probabilistic generating function
基于概率的生成函数
对于一个离散随机变量 \(X\in N\) ,其概率生成函数为 \(F(z)=\sum\limits_{i=0}P(X=i)z^i\) ,\(E(X)=\sum\limits_{i=0}P(X=i)i=F'(1)\) 。
可以进一步拓展到 \(E(X^{\underline k})=F^{(k)}(1)\) (以下用 \(F(x)^k\) 表示幂次,用 \(F^k(x)\) 表示求导)
方差计算式:\(\text{Var}(X)=E((X-E(X))^2)=E(X^2)-E(X)^2\) .
下面用 PGF
来描述方差。
注意到 \(X^{\underline 2}+X^{\underline 1}=X^2\) ,而 \(E(X^{\underline 2})=F''(1)\) ,有
所以方差就是 \(F''(1)+F'(1)-F'(1)^2\) 。
实战演练
P4548
:典型的掷硬币模型,即进行某个游戏直到终止态,问期望。
P3706
:上一题的多终止态版本。
HDU4652
:终止态全部等价的版本。不过用 DP 做更方便。