又要杂题选讲了qwq,由于本人太菜而且暑假集训后完全在搞whk啥题都没刷,于是只能讲模板了/kk
一.啥是生成函数
生成函数是一个晾衣绳,我们把一系列的数字挂在上面以供显示。——《\(Generating\) \(Funtionology\)》
上面那句话是什么意思,我们姑且不谈反正我也不知道是什么意思。我们从中大概可以感受到,生成函数是一种处理序列问题的工具,那么我们接下来再看这本书里的另一端话:
假设我们有一个问题,答案是一系列的数字\(\{ a_i \}\),我们想知道这个序列是什么。我们会得到什么样的答案呢?
一个简单的公式将是最好的。如果我们发现对于每个 \(n=0,1,2,…,a_n=n^2+3\),那么毫无疑问我们已经“回答”了这个问题。
但是如果没有简单的公式来计算未知序列?毕竟,有些序列是复杂的——举个令人毛骨悚然的例子,假设未知序列是\(\{ 2,3,5,7,11,13,17,19,…,\}\) 其中 \(a_n\) 是第 \(n\) 个素数。那么,它指望得到任何一种简单的公式都是不合理的。
生成函数给你提供另外一种解决这种问题的有力方式,虽然给序列成员一个简单的公式是不可能的,但是我们可以给出一个关于幂级数和的简单公式,它的系数就是我们要找的序列。——《\(Generating\) \(Funtionology\)》
好的,我们现在已经知道生成函数是用来干什么的了,接下来我们直接切入正题——
二.普通生成函数 \(opsgf\) 的定义
我们定义一个序列 \(\{ a_i \}\) 的普通生成函数为
\(\{ a_i \}\) 既可以是有穷序列,也可以是无穷序列,下面有一些常见的例子:
- 序列 \(\{1,2,3\}\) 的普通生成函数是 \(F(x)=1+2x+3x^2\)。
- 序列 \(\{1,1,...,1\}\) 的普通生成函数是 \(\sum\limits_{k}{x^k}\)。
换句话说,如果序列 \(\{ a_i \}\) 有通项公式,那么他的生成函数的系数就应该是他的通项公式。
知道了上面的东西并没有任何用处,我们不知道怎么应用它,而他的用法——求封闭形式,就要从我们提到过的序列 \(\{1,1,...,1\}\) 的普通生成函数
讲起——
三.普通生成函数的封闭形式
大家可能在很多地方都见到过这样一个定理:
这个定理的正确性看起来一点也不显然嘛,那我们换个角度看问题:
有个非常显然的性质:
其实他就相当于把 \(F(x)\) 整体向右平移一位,然后在前面补 \(1\) ,其实这种方法类似扰动法的解方程,我们把上面的那个方程解了,就得到了这个定理
这玩意的收敛半径是 \(|x| \leq 1\)
如果你理解了上面的过程,那么恭喜你,你已经初步掌握了生成函数的处理技巧之一——求封闭形式。
我们把上面的过程称为求封闭形式,把从 \(\frac{1}{1-x}\) 推回原来的函数称为级数展开,而且显然这两个东西是可以互推的。
好的,那么在我们初步学会了普通生成函数之后,我们来看一个应用。
四.利用普通生成函数解斐波那契数列的通项问题
- 问题:定义斐波那契数列 \(f_i=f_{i-1}+f_{i-2},f_1=f_2=1\),求 \(\{ f_i \}\) 通项。
解:首先设 \(\{ f_i \}\) 的普通生成函数为
这个套路在《\(Generating\) \(Funtionology\)》里面被称为 \(Snake\) \(Oil\) \(Method\),继续按套路,设
其实这个套路跟我们上面求 \(\sum\limits_{k \geq 0}{x^k}\) 的作用是一样的,都是通过发现 \(F(x)\) 的性质从而解出他的封闭形式,那么有:
结合 \(G(x)=F(x)-x-x^2\),移项解得:
这就是斐波那契数列的生成函数。
到了这一步,我们将它级数展开,按套路设:
可解得 \(x_1=\frac{1 + \sqrt 5}{2},x_2=\frac{1 - \sqrt 5}{2}\),整理上式有:
- \(\frac{x}{1-x·x_2}=A+\frac{1-x·x_1}{1-x·x_2}B\)
- \(\frac{x}{1-x·x_1}=A+\frac{1-x·x_2}{1-x·x_1}B\)
这个是一个非常经典的 \(trick\),推很多别的生成函数的式子的时候都可以这样子做,在这两个式子中分别令 \(x·x_1=1,x·x_2=1\),最后可解出:
将 \(F(x)=\frac{A}{1-x·x_1}+\frac{B}{1-x·x_2}\)级数展开:
将 \(A,B,x_1,x_2\) 全部代入,最后有:
于是有斐波那契数列的通项公式:
好的,看来我们现在已经成功应用普通生成函数解决了一些有趣的问题了,下面我们对上面的思想/套路作一些总结:
- 首先,我们要求序列 \(\{ a_i \}\) 的通项公式,那么就把它的普通生成函数 \(F(x)\) 设出来
- 求出 \(F(x)\) 的封闭形式
- 再把 \(F(x)\) 的封闭形式展开,取系数,就得到了答案
好哇,这就是我们今天杂题选讲的全部内容了,大家再见!
好吧,既然是杂题选讲,还是得讲点题的。
五.例题:LG P2000 拯救世界
我们将题目中的限制所代表的生成函数列出来(具体我们讲题的时候解释):
然后把他们全部乘起来,得到
有一个这样子的结论(广义二项式定理):
那么我们上面得到的式子就是 \(n=5\) 的情况,所以:
所以答案就是 \({n+4} \choose {n}\),这题做完了。
凑合着放一下代码
n=int(input())
print((n+1)*(n+2)*(n+3)*(n+4)//24)
你问我为啥写 \(Python\)?
是不可能写高精度的,这辈子都不可能再写高精度的