1.11.11.1 普通生成函数 OGFOGFOGF:F(x)=∑n=0∞fnxnF(x)=\sum_{n=0}^{\infty}f_nx^nF(x)=∑n=0∞fnxn
定义SEQASEQ_ASEQA是AAA中元素排成的序列组成的集合,一个序列的大小定义为各元素大小之和,那么SEQASEQ_ASEQA的OGFOGFOGF:
SEQA(x)=1+A(x)+A2(x)+...+An(x)=11−A(x)SEQ_A(x)=1+A(x)+A^2(x)+...+A^n(x)=\frac{1}{1-A(x)}SEQA(x)=1+A(x)+A2(x)+...+An(x)=1−A(x)1 。
1.21.21.2 背包计数问题:有kkk种物品,每种物品有容量viv_ivi和数量nin_ini,问组合出容量为VVV的方案数。
F(x)=∏i=1k(1+xvi+x2vi+...+xnivi)=∏i=1nx(ni+1)vi−1xvi−1F(x)=\prod_{i=1}^k(1+x^{v_i}+x^{2v_i}+...+x^{n_iv_i})=\prod_{i=1}^n\frac{x^{(n_i+1)v_i}-1}{x^{v_i}-1}F(x)=∏i=1k(1+xvi+x2vi+...+xnivi)=∏i=1nxvi−1x(ni+1)vi−1
假设背包有无穷种物品,每种物品的体积为iii,个数也无限,把nnn的正整数拆分的方案数记作p(n)p(n)p(n),ppp也叫分拆数。
不难得到p(n)p(n)p(n)的生成函数:F(x)=∏i=1∞11−xiF(x)=\prod_{i=1}^{\infty}\frac{1}{1-x^i}F(x)=∏i=1∞1−xi1
两边取对数,有lnF(x)=−∑i=1∞ln(1−xi)\ln F(x)=-\sum_{i=1}^{\infty}\ln(1-x^i)lnF(x)=−∑i=1∞ln(1−xi)
在modxn+1\bmod \ x^{n+1}mod xn+1意义下可以把无穷和变为有限的:lnF(x)=−∑i=1nln(1−xi)\ln F(x)=-\sum_{i=1}^n\ln(1-x^i)lnF(x)=−∑i=1nln(1−xi)
求右边的麦克劳林展式:
lnF(x)=−∑i=1nln(1−xi)=∑i=1n∑j=1∞xijj=∑j=1∞1j∑i=1nxij=∑j=1n1j∑i=1⌊nj⌋xij\ln F(x)=-\sum_{i=1}^n\ln(1-x^i)=\sum_{i=1}^n\sum_{j=1}^{\infty}\frac{x^{ij}}{j}=\sum_{j=1}^\infty\frac{1}{j}\sum_{i=1}^nx^{ij}=\sum_{j=1}^n\frac{1}{j}\sum_{i=1}^{\lfloor\frac{n}{j}\rfloor}x^{ij}lnF(x)=−∑i=1nln(1−xi)=∑i=1n∑j=1∞jxij=∑j=1∞j1∑i=1nxij=∑j=1nj1∑i=1⌊jn⌋xij
右边和式可以处理出来,再对其求多项式exp\expexp即可,复杂度O(nlogn)O(n\log n)O(nlogn)。
1.31.31.3 指数生成函数 EGFEGFEGF:F(x)=∑n=0∞fnxnn!F(x)=\sum_{n=0}^{\infty}f_n\frac{x^n}{n!}F(x)=∑n=0∞fnn!xn
一次积分相当于右移一项,一次求导相当于左移一项
∫F(x)=∑n=1∞fn−1xnn!\int F(x)=\sum_{n=1}^\infty f_{n-1}\frac{x^n}{n!}∫F(x)=∑n=1∞fn−1n!xn,F′(x)=∑n=0∞fn+1xnn!F'(x)=\sum_{n=0}^{\infty}f_{n+1}\frac{x^n}{n!}F′(x)=∑n=0∞fn+1n!xn
两个函数的卷积:hn=∑k=0n(nk)fkgn−kh_n=\sum_{k=0}^n\binom{n}{k}f_kg_{n-k}hn=∑k=0n(kn)fkgn−k,也把序列hhh叫做序列fff和ggg的二项卷积
1.41.41.4 组合意义:OGFOGFOGF考虑的是多重集的组合问题,EGFEGFEGF考虑的是多重集的排列问题。
1.51.51.5 有时我们需要考虑带标号的组合对象,如标号图。
定义SETASET_ASETA是AAA中元素任意拼接组成的集合(拼接时不考虑顺序),SETASET_ASETA的EGFEGFEGF:
SETA(x)=1+A(x)+A2(x)2+...+An(x)n!=exp(A(x))SET_A(x)=1+A(x)+\frac{A^2(x)}{2}+...+\frac{A^n(x)}{n!}=\exp(A(x))SETA(x)=1+A(x)+2A2(x)+...+n!An(x)=exp(A(x))
一个带标号的简单无向图是若干个联通分量不考虑顺序拼接成的,GGG是简单无向图的EGFEGFEGF,CCC是简单连通图的EGFEGFEGF,那么:
G(x)=∑n=0∞2(n2)xnn!G(x)=\sum_{n=0}^{\infty}2^{\binom{n}{2}}\frac{x^n}{n!}G(x)=∑n=0∞2(2n)n!xn,exp(C(x))=G(x)\exp(C(x))=G(x)exp(C(x))=G(x)
所以C(x)=lnG(x)C(x)=\ln G(x)C(x)=lnG(x)
1.61.61.6 集合划分问题:集合SSS的一个划分是把SSS分成两两不相交的非空子集,并且它们的并是SSS。
不难发现,划分的结果是由若干个子集无序拼接起来的。对于一个集合而言,不能选空集,而分出1,2,...,n1,2,...,n1,2,...,n个的方案数都只有一种,只有在拼接的时候指定编号。
故一个集合分出元素的EGFEGFEGF是exp(x)−1\exp(x)-1exp(x)−1,集合的划分的EGFEGFEGF是exp(exp(x)−1)\exp(\exp(x)-1)exp(exp(x)−1)。
bell\text{bell}bell数BnB_nBn是基数为nnn的集合划分数目,之前我们推导出了BnB_nBn的EGFEGFEGF是exp(exp(x)−1)\exp(\exp(x)-1)exp(exp(x)−1),可以快速求前nnn个bell\text{bell}bell数。
1.71.71.7 第二类Stirling\text{Stirling}Stirling数:S(n,m)S(n,m)S(n,m)表示将nnn个不同的元素划分称mmm个集合的方案数。
我们可以写出第二类Stirling\text{Stirling}Stirling数的EGFEGFEGF,假设mmm是一个定值,那么有
∑n=0∞anxnn!=(exp(x)−1)mm!\sum_{n=0}^{\infty}a_n\frac{x^n}{n!}=\frac{(\exp(x)-1)^m}{m!}∑n=0∞ann!xn=m!(exp(x)−1)m,an=S(n,m)a_n=S(n,m)an=S(n,m)
不难求得S(n,m)=1m!∑k=0m(−1)m−k(mk)knS(n,m)=\frac{1}{m!}\sum_{k=0}^m(-1)^{m-k}\binom{m}{k}k^nS(n,m)=m!1∑k=0m(−1)m−k(km)kn
把m!m!m!放到和式里面:S(n,m)=∑k=0m(−1)m−k(m−k)!knk!S(n,m)=\sum_{k=0}^m\frac{(-1)^{m-k}}{(m-k)!}\frac{k^n}{k!}S(n,m)=∑k=0m(m−k)!(−1)m−kk!kn
这是一个卷积的形式,给定nnn,可以快速算出S(n,m)(1≤m≤n)S(n,m)(1\le m\le n)S(n,m)(1≤m≤n)
给定mmm,用∑n=0∞anxnn!=(exp(x)−1)mm!\sum_{n=0}^{\infty}a_n\frac{x^n}{n!}=\frac{(\exp(x)-1)^m}{m!}∑n=0∞ann!xn=m!(exp(x)−1)m,an=S(n,m)a_n=S(n,m)an=S(n,m)可以快速算出前nnn个S(n,m)S(n,m)S(n,m)
复杂度O(nlogn)O(n\log n)O(nlogn)。这就是第二类斯特林数行/列
1.81.81.8 第一类Sirling\text{Sirling}Sirling数:[nm]\begin{bmatrix}n \\ m\end{bmatrix}[nm]表示将nnn个不同元素划分为kkk个互不区分的非空轮换的方案数。
递推式:[nm]=[n−1m−1]+(n−1)[n−1m]\begin{bmatrix}n \\ m\end{bmatrix}=\begin{bmatrix}n-1 \\ m-1\end{bmatrix}+(n-1)\begin{bmatrix}n-1 \\ m\end{bmatrix}[nm]=[n−1m−1]+(n−1)[n−1m]
1.8.11.8.11.8.1 同一行第一类斯特林数计算
我们构造同行第一类斯特林数的生成函数,即Fn(x)=∑i=0n[nm]xiF_n(x)=\sum_{i=0}^n\begin{bmatrix}n \\ m\end{bmatrix}x^iFn(x)=∑i=0n[nm]xi
根据递推公式,不难写出:Fn(x)=(n−1)Fn−1(x)+xFn−1(x)F_n(x)=(n-1)F_{n-1}(x)+xF_{n-1}(x)Fn(x)=(n−1)Fn−1(x)+xFn−1(x)
于是Fn(x)=∏i=0n−1(x+i)F_n(x)=\prod_{i=0}^{n-1}(x+i)Fn(x)=∏i=0n−1(x+i)
这其实是xxx的nnn次上升阶乘幂,记作xn‾x^{\overline n}xn。用上升幂相关做法可以O(nlogn)O(n\log n)O(nlogn)求出。
1.8.21.8.21.8.2 同一列第一类斯特林数的计算
显然,单个轮换的指数型生成函数为F(x)=∑i=1n(i−1)!xii!F(x)=\sum_{i=1}^n\frac{(i-1)!x^i}{i!}F(x)=∑i=1ni!(i−1)!xi
它的kkk次幂就是[ik]\begin{bmatrix}i \\ k\end{bmatrix}[ik]的指数型生成函数,O(nlogn)O(n\log n)O(nlogn)计算即可。
1.91.91.9 上升幂的计算
考虑倍增,x2n‾=xn‾(x+n)n‾x^{\overline {2n}}=x^{\overline n}(x+n)^{\overline n}x2n=xn(x+n)n
于是现在我们有多项式f(x)f(x)f(x),要求f(x+c)f(x+c)f(x+c)的值
不难得到f(x+c)f(x+c)f(x+c)可以二项式展开然后卷积求出。
复杂度O(nlogn)O(n\log n)O(nlogn) 。
用上升幂求第二类斯特林数的列:
利用递推式{nm}={n−1m−1}+m{n−1m}\begin{Bmatrix}n \\ m\end{Bmatrix}=\begin{Bmatrix}n-1 \\ m-1\end{Bmatrix}+m\begin{Bmatrix}n-1 \\ m\end{Bmatrix}{nm}={n−1m−1}+m{n−1m}
设Fk(x)=∑i=0∞{ik}xiF_k(x)=\sum_{i=0}^{\infty}\begin{Bmatrix}i \\ k\end{Bmatrix}x^iFk(x)=∑i=0∞{ik}xi
不难发现Fk(x)=xFk−1(x)+kxFk(x)F_k(x)=xF_{k-1}(x)+kxF_k(x)Fk(x)=xFk−1(x)+kxFk(x),那么Fk(x)=x1−kxFk−1(x)F_k(x)=\frac{x}{1-kx}F_{k-1}(x)Fk(x)=1−kxxFk−1(x)
那么Fk(x)=∏i=1kx1−ix=xk(∏i=1k(1−ix))−1F_k(x)=\prod_{i=1}^k\frac{x}{1-ix}=x^k(\prod_{i=1}^k(1-ix))^{-1}Fk(x)=∏i=1k1−ixx=xk(∏i=1k(1−ix))−1
考虑算∏i=1k(1−ix)\prod_{i=1}^k(1-ix)∏i=1k(1−ix)。
∏i=1k(1−ix)=xk∏i=1k(x−1−i)\prod_{i=1}^k(1-ix)=x^k\prod_{i=1}^k(x^{-1}-i)∏i=1k(1−ix)=xk∏i=1k(x−1−i)
注意到∏i=1k(x−i)\prod_{i=1}^k(x-i)∏i=1k(x−i)翻转后就能得到xk∏i=1k(x−1−i)x^k\prod_{i=1}^k(x^{-1}-i)xk∏i=1k(x−1−i)
那么算∏i=1k(x−i)=xk+1‾x\prod_{i=1}^k(x-i)=\frac{x^{\underline {k+1}}}{x}∏i=1k(x−i)=xxk+1 即可。
复杂度O(nlogn)O(n\log n)O(nlogn)。
本文链接:https://www.ngui.cc/article/show-845608.html