详解生成函数

Posted top_secret的小尛博客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了详解生成函数相关的知识,希望对你有一定的参考价值。

参考资料

指数型生成函数

数列\\(\\{a_i\\}\\)的指数型生成函数(EGF)是\\(A(x)=\\sum_{i=0}^\\infty\\frac{a_i}{i!}x_i\\)

\\(C=A*B\\),则

\\[\\begin{aligned} C &= (\\sum_{i\\ge 0}\\frac{a_i}{i!})(\\sum_{i\\ge 0}\\frac{b_i}{i!}) \\\\ &= \\sum_{i\\ge0}x^i\\sum_{j=0}^i\\frac{a_jb_{i-j}}{j!(i-j)!} \\\\ &= \\sum_{i\\ge0}\\frac{\\sum_{j=0}^i\\frac{i!}{j!(i-j)!}a_jb_{i-j}}{i!}x_i \\end{aligned} \\]

\\[\\boxed{c_i=\\sum_{j=0}^i\\binom{i}{j}a_jb_{i-j}} \\]

多项式\\(\\exp\\)\\(\\ln\\)的意义

\\(A\\)为表示蓝色的带编号树的个数的生成函数(即,\\(a_n\\)表示\\(n\\)个节点的带编号树的个数),\\(B\\)代表红色的带编号树的个数,则\\(A*B\\)代表一个两棵树的森林,一棵为红色,一颗为蓝色,这样的森林的个数。

又因为红色与蓝色可以交换,若不考虑颜色,同一个森林实际上被计数了两遍,故\\(\\frac{A^2}{2!}=A*A/2\\)代表两棵树的森林的个数。

以此类推,枚举森林中树的个数\\(i\\),则\\(C=\\sum_{i\\ge 0}\\frac{A^i}{i!}\\)代表了森林的个数。

由于对\\(x\\in\\R\\)\\(e^x=\\sum_{i\\ge0}\\frac{x^i}{i!}\\)(在\\(x=0\\)处泰勒展开),如果令\\(x=A\\),我们可以记\\(C=e^A\\)。这样,我们得到了多项式\\(\\exp\\)的定义:

\\[\\boxed{e^A=\\sum_{i\\ge0}\\frac{A^i}{i!}} \\]

其中\\(A\\)是一个生成函数,\\(A^i\\)表示多项式\\(A\\)\\(i\\)次方。同样,通过泰勒展开的方法,我们可以得到多项式\\(\\ln\\)的定义。

多项式运算的实现

多项式乘法逆

\\(A(x)=\\sum_{i\\ge 0}a_ix^i\\),且有\\(a_0\\ne 0\\),则其存在唯一的逆\\(B(x)=\\sum_{i\\ge 0}b_ix^i\\),满足:

\\[c_i=\\sum_{0\\le j\\le i}a_{j}b_{i-j}=[i=0]\\nonumber \\]

显然,可以如此递归地定义\\(b_i\\)

考虑如何求\\(B(x)\\bmod x^n\\),显然\\(n=1\\)\\(b_0=a_0^{-1}\\)

若已求得\\(\\bmod x^{\\lceil n/2\\rceil}\\)的答案\\(B_0\\),考虑如何推得\\(B\\)

我们显然有:

\\[(B-B_0) \\equiv 0 \\pmod{x^{\\lceil n/2\\rceil}} \\nonumber \\]

对两边平方,得

\\[\\begin{aligned} (B-B_0)^2 &\\equiv 0 \\\\ B^2-2BB_0+B_0^2 &\\equiv 0 \\\\ B^2 &\\equiv 2BB_0 - B_0^2 \\\\ B &\\equiv 2B_0-B_0^2B^{-1} \\end{aligned}\\pmod{x^n} \\]

其中最后一步是在两边乘了一个\\(B^{-1}\\)。由于\\(A\\)\\(B\\)互为乘法逆,\\(B^{-1}\\equiv A\\),故:

\\[\\boxed{B\\equiv B_0(2-B_0A)}\\pmod{x^n} \\label{inv} \\]

递归计算即可。

多项式\\(\\ln\\)

\\(B=\\ln A\\),将其两边取导数。由\\(\\mathrm {\\frac{d}{dx}}\\ln A=\\frac{1}{A}A\'\\),有\\(B\'=\\frac{A\'}{A}\\),故

\\[\\boxed{B = \\int\\frac{A\'}{A}\\mathrm{dx}} \\]

\\(\\eqref{inv}\\)求出\\(A^{-1}\\)即可。

牛顿迭代法

泰勒展开

\\(G(x)\\)为一个定义在\\(\\mathbb R\\)上函数,则\\(G(x)\\)\\(x_0\\)处的泰勒展开(一个函数,使得\\(x_0\\)处的\\(0\\)阶、\\(1\\)阶、……导数都相等(可类比拉格朗日插值公式))为:

\\[\\begin{eqnarray} G(x) &=& G(x_0)+G\'(x_0)(x-x_0)+\\frac{G\'\'(x_0)(x-x_0)^2}{2!}\\cdots\\nonumber \\\\ &=& \\sum_{i=0}^{\\infty}\\frac{G^{(i)}(x_0)}{i!} \\label{taylor} \\end{eqnarray} \\]

注意,由于\\(x_0\\)固定,\\(G(x_0)\\)\\(G\'(x_0)\\)等都是常数。

为了方便接下来的讨论,我们设\\(G(x)=f(x)+b\\),其中\\([x^0]f(x)=0\\)(即\\(f(0)=0\\))。

我们扩大\\(G\\)的定义域,使得\\(G\\)对于所有级数\\(F\\)都有定义,为\\(G(F)=f(F)+b\\),其中\\(b\\)也可以是一个(常)级数,\\(f\\)是一个函数。同样\\(f\\)的系数也可以是常级数。

我们的任务是求\\(G(F)\\equiv 0\\)\\(\\bmod x^n\\)意义下的解。

考虑倍增,设\\(F_0\\)表示\\(\\bmod x^{\\lceil x/2\\rceil}\\)意义下的解,有(将\\(G\\)\\(F_0\\)处泰勒展开\\(\\eqref{taylor}\\)

\\[0\\equiv G(F)\\equiv G(F_0)+(F-F_0)G\'(F_0)+(F-F_0)^2R\\pmod{x^n}\\nonumber \\]

其中\\(R\\)是一个关于\\(F\\)的函数。由于\\((F-F_0)\\bmod x^{\\lceil n/2\\rceil}=0\\),可知\\((F-F_0)^2\\bmod x^{n}=0\\),故

\\[\\begin{aligned} G(F_0)+(F-F_0)G\'(F_0) &\\equiv 0 \\\\ FG\'(F_0) &\\equiv F_0G\'(F_0)-G(F_0) \\\\ \\end{aligned}\\pmod{x^n} \\]

两边除以\\(G\'(F_0)\\),我们获得了:

\\[\\boxed{F \\equiv F_0-\\frac{G(F_0)}{G\'(F_0)}} \\pmod{x^n}\\label{newton} \\]

多项式\\(\\exp\\)

\\(B=e^A\\),则\\(\\ln B=A\\)。我们相当于要解\\(\\ln B-A=0\\)

\\(F(B)=\\ln B-A\\),直接使用\\(\\eqref{newton}\\),得:

\\[\\begin{aligned} B &\\equiv B_0-\\frac{\\ln B_0-A}{B_0^{-1}} \\\\ \\end{aligned} \\]

\\[\\boxed{B \\equiv B_0(1-\\ln B_0+A)}\\label{exp} \\]

倍增即可,需要用到多项式\\(\\ln\\)

例题

以上是关于详解生成函数的主要内容,如果未能解决你的问题,请参考以下文章

生成函数详解

生成器详解

C语言rand函数生成随机数详解和示例

python基础知识~ 函数详解2

ES6新特性三: Generator(生成器)函数详解

2018-06-20-Python全栈开发day19-生成器函数详解