首页 > 编程学习 > 【学习笔记】生成函数入门

1.11.11.1 普通生成函数 OGFOGFOGFF(x)=∑n=0∞fnxnF(x)=\sum_{n=0}^{\infty}f_nx^nF(x)=n=0fnxn

定义SEQASEQ_ASEQAAAA中元素排成的序列组成的集合,一个序列的大小定义为各元素大小之和,那么SEQASEQ_ASEQAOGFOGFOGF

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)=1A(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=1nxvi1x(ni+1)vi1

假设背包有无穷种物品,每种物品的体积为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=11xi1

两边取对数,有ln⁡F(x)=−∑i=1∞ln⁡(1−xi)\ln F(x)=-\sum_{i=1}^{\infty}\ln(1-x^i)lnF(x)=i=1ln(1xi)

modxn+1\bmod \ x^{n+1}mod xn+1意义下可以把无穷和变为有限的:ln⁡F(x)=−∑i=1nln⁡(1−xi)\ln F(x)=-\sum_{i=1}^n\ln(1-x^i)lnF(x)=i=1nln(1xi)

求右边的麦克劳林展式:

ln⁡F(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(1xi)=i=1nj=1jxij=j=1j1i=1nxij=j=1nj1i=1jnxij

右边和式可以处理出来,再对其求多项式exp⁡\expexp即可,复杂度O(nlog⁡n)O(n\log n)O(nlogn)

1.31.31.3 指数生成函数 EGFEGFEGFF(x)=∑n=0∞fnxnn!F(x)=\sum_{n=0}^{\infty}f_n\frac{x^n}{n!}F(x)=n=0fnn!xn

一次积分相当于右移一项,一次求导相当于左移一项

∫F(x)=∑n=1∞fn−1xnn!\int F(x)=\sum_{n=1}^\infty f_{n-1}\frac{x^n}{n!}F(x)=n=1fn1n!xnF′(x)=∑n=0∞fn+1xnn!F'(x)=\sum_{n=0}^{\infty}f_{n+1}\frac{x^n}{n!}F(x)=n=0fn+1n!xn

两个函数的卷积:hn=∑k=0n(nk)fkgn−kh_n=\sum_{k=0}^n\binom{n}{k}f_kg_{n-k}hn=k=0n(kn)fkgnk,也把序列hhh叫做序列fffggg的二项卷积

1.41.41.4 组合意义:OGFOGFOGF考虑的是多重集的组合问题,EGFEGFEGF考虑的是多重集的排列问题。

1.51.51.5 有时我们需要考虑带标号的组合对象,如标号图。

定义SETASET_ASETAAAA中元素任意拼接组成的集合(拼接时不考虑顺序),SETASET_ASETAEGFEGFEGF

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是简单无向图的EGFEGFEGFCCC是简单连通图的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=02(2n)n!xnexp⁡(C(x))=G(x)\exp(C(x))=G(x)exp(C(x))=G(x)

所以C(x)=ln⁡G(x)C(x)=\ln G(x)C(x)=lnG(x)

1.61.61.6 集合划分问题:集合SSS的一个划分是把SSS分成两两不相交的非空子集,并且它们的并是SSS

不难发现,划分的结果是由若干个子集无序拼接起来的。对于一个集合而言,不能选空集,而分出1,2,...,n1,2,...,n1,2,...,n个的方案数都只有一种,只有在拼接的时候指定编号。

故一个集合分出元素的EGFEGFEGFexp⁡(x)−1\exp(x)-1exp(x)1,集合的划分的EGFEGFEGFexp⁡(exp⁡(x)−1)\exp(\exp(x)-1)exp(exp(x)1)

bell\text{bell}bellBnB_nBn是基数为nnn的集合划分数目,之前我们推导出了BnB_nBnEGFEGFEGFexp⁡(exp⁡(x)−1)\exp(\exp(x)-1)exp(exp(x)1),可以快速求前nnnbell\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=0ann!xn=m!(exp(x)1)man=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!1k=0m(1)mk(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(mk)!(1)mkk!kn

这是一个卷积的形式,给定nnn,可以快速算出S(n,m)(1≤m≤n)S(n,m)(1\le m\le n)S(n,m)(1mn)

给定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=0ann!xn=m!(exp(x)1)man=S(n,m)a_n=S(n,m)an=S(n,m)可以快速算出前nnnS(n,m)S(n,m)S(n,m)

复杂度O(nlog⁡n)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]=[n1m1]+(n1)[n1m]

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)=(n1)Fn1(x)+xFn1(x)

于是Fn(x)=∏i=0n−1(x+i)F_n(x)=\prod_{i=0}^{n-1}(x+i)Fn(x)=i=0n1(x+i)

这其实是xxxnnn次上升阶乘幂,记作xn‾x^{\overline n}xn。用上升幂相关做法可以O(nlog⁡n)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!(i1)!xi

它的kkk次幂就是[ik]\begin{bmatrix}i \\ k\end{bmatrix}[ik]的指数型生成函数,O(nlog⁡n)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(nlog⁡n)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}={n1m1}+m{n1m}

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)=xFk1(x)+kxFk(x),那么Fk(x)=x1−kxFk−1(x)F_k(x)=\frac{x}{1-kx}F_{k-1}(x)Fk(x)=1kxxFk1(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=1k1ixx=xk(i=1k(1ix))1

考虑算∏i=1k(1−ix)\prod_{i=1}^k(1-ix)i=1k(1ix)

∏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(1ix)=xki=1k(x1i)

注意到∏i=1k(x−i)\prod_{i=1}^k(x-i)i=1k(xi)翻转后就能得到xk∏i=1k(x−1−i)x^k\prod_{i=1}^k(x^{-1}-i)xki=1k(x1i)

那么算∏i=1k(x−i)=xk+1‾x\prod_{i=1}^k(x-i)=\frac{x^{\underline {k+1}}}{x}i=1k(xi)=xxk+1 即可。

复杂度O(nlog⁡n)O(n\log n)O(nlogn)


本文链接:https://www.ngui.cc/article/show-845608.html
Copyright © 2010-2022 ngui.cc 版权所有 |关于我们| 联系方式| 豫B2-20100000