- UPD on 8.11:纠正了关于斐波那契数列待定系数法的方程
- UPD on 8.12:纠正了关于收敛半径的描述
又要杂题选讲了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}) 的普通生成函数是 (sumlimits_{k}{x^k})。
换句话说,如果序列 ({ a_i }) 有通项公式,那么他的生成函数的系数就应该是他的通项公式。
知道了上面的东西并没有任何用处,我们不知道怎么应用它,而他的用法——求封闭形式,就要从我们提到过的序列 ({1,1,...,1}) 的普通生成函数
讲起——
三.普通生成函数的封闭形式
大家可能在很多地方都见到过这样一个定理:
这个定理的正确性看起来一点也不显然嘛,那我们换个角度看问题:
有个非常显然的性质:
其实他就相当于把 (F(x)) 整体向右平移一位,然后在前面补 (1) ,其实这种方法类似扰动法的解方程,我们把上面的那个方程解了,就得到了这个定理
这玩意的收敛半径是 (|x| < 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),继续按套路,设
其实这个套路跟我们上面求 (sumlimits_{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}=B+frac{1-x·x_2}{1-x·x_1}A)
这个是一个非常经典的 (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)?
是不可能写高精度的,这辈子都不可能再写高精度的
UPD. (Py)被卡了,所以还是老实写高精压位或者 (ntt) 优化吧/kk