曾经有人问过我:“斐波那契数列的生成函数长啥样?”
。。。所以这东西我还是写一发吧
它有什么用?它没啥用。。。
1.齐次线性递推数列
定义:给定常数 k,a1,a2,...,ak,h0,h1,...,hk−1 ,构造如下数列:
hn={hna1hn−1+a2hn−2+...+akhn−kn<kn≥k
称作齐次线性递推数列。
多项式
F(x)=h0+h1x+h2x2+...
被称作这个数列的一般生成函数。
说到齐次线性递推数列,最经典的就是斐波那契数列。
定义不用给了吧……
斐波那契数列的生成函数是这个样子的:
F(x)=1+x+2x2+3x3+5x4+8x5+...
如何用一些有限项的多项式来表示这个级数?
我们构造这样一个函数:
A(x)=1−x−x2
易验证:
F(x)A(x)=1
即:
F(x)=11−x−x2
这是为什么呢?
原因很简单,对于 ∀n≥2 ,
[n](F(x)A(x))=[n]F(x)−[n−1]F(x)−[n−2]F(x)=0
其中 [n]F(x) 代表 F(x) 的 n 次项系数
这个结论有一些很好玩的结果,比如代入 x=0.01 ,有:
10.9899=1.010203050813213455...
我们还可以知道,如果把斐波那契数列写成这样:
1
11
112
1113
11115
111118
1111113
11111121
…
然后把每一位从上到下加起来,将会出现长度为89的循环节,因为 10.89 是个有理数……
我们可以把这个推广到一般形式:
对于递推式
hn=a1hn−1+a2hn−2+...+akhn−k
的生成函数
F(x)=h0+h1x+h2x2+...
构造函数:
H(x)=h0+h1x+h2x2+...+hk−1xk−1
A(x)=1−a1x−a2x2−...−akxk
则:
F(x)A(x)=H(x)A(x) mod xk
F(x)=H(x)A(x) mod xkA(x)
可以看出这个形式十分的优雅,不过我并不知道这个优雅的形式与数列本质有什么关联……
这东西有啥用?
给出一个 k 阶线性递推方程,求第 n 项, n,k≤105
暴力 O(nk) ,矩乘 k3logk ,全挂了……
FFT可以 O(nlogn) 。
叫我毒瘤。
2.非齐次线性递推数列
定义:给定常数 k,a1,a2,...,ak,h0,h1,...,hk−1 ,构造如下数列:
hn={hna1hn−1+a2hn−2+...+akhn−k+g(n)n<kn≥k
称作非齐次线性递推数列。
其中 g(n) 是关于 n 的函数,可以是常函数
要求用一些有限项多项式来表示级数:
F(x)=h0+h1x+h2x2+...
和之前一样,构造多项式:
H(x)=h0+h1x+h2x2+...+hk−1xk−1
A(x)=1−a1x−a2x2−...−akxk
G(x)=g(0)+g(1)x+g(2)x2+...
则:
F(x)A(x)=H(x)A(x) mod xk+(G(x)−G(x) mod xk)
F(x)=[H(x)A(x)−G(x)] mod xk+G(x)A(x)
所以如果 G(x) 能被有限项多项式表示的话就做完了。。。
若 g(n)=1 ,则 G(x)=1+x+x2+...=11−x
若 g(n)=n ,则 G(x)=x+2x2+3x3...=x(1−x)2
若 g(n)=n2 ,则 G(x)=x+4x2+9x3...=x(x+1)(1−x)3
以此类推,如果 g 函数是个多项式的话还是可以表示出来的
3.卡特兰数列
定义:
hn={1h0hn−1+h1hn−2+...+hn−1h0n=0n≥1
求 F(x)=h0+h1x+h2x2+...
容易发现这个递推式本身就是一个卷积,所以我们直接把这个多项式自乘一下
F2(x)=h1+h2x+h3x2+...=F(x)−1x
解得
F(x)=1−1−4x√2x
即为卡特兰数列的生成函数。
4.。。。我并不知道这数列叫啥名字,暂且称作广义卡特兰数列吧。。。
我们都知道卡特兰数列的第 n 项代表 n 个元素的入栈出栈序列数,即从原点走到 (n,n) 不跨越 y=x 的方案数
那么,定义广义卡特兰数列 hk(n) 表示 n+k 个元素入栈出栈后栈中剩余 k 个元素的入栈出栈序列数,即从原点走到 (n+k,n) 不跨越 y=x 的方案数
求生成函数:
Fk(x)=hk(0)+hk(1)x+hk(2)x2+...
考虑栈中剩余的这 k 个元素,第 i 个元素放进去之后就不动了,然后经历了一些入栈弹栈,然后塞入第 i+1 个元素
换句话说我们可以把第 i 个元素看做栈底,然后进行了一堆入栈出栈操作,然后栈空了,然后塞进第 i+1 个元素……
如果中间这些走了个过场的元素数量为 s ,那么方案数是多少?
h0(s) ,即卡特兰数列第 s 项
于是问题就简单了,我们把 n 个元素的序列分成 k+1 段,如果一段有 s 个元素,方案数是 h0(s) ,求方案数
会生成函数的看到这里已经懂了吧。
构造函数 H(x)=h0(0)+h0(1)x+h0(2)x2+...=1−1−4x√2x
则 Fk(x)=Hk+1(x)=(1−1−4x√2x)k+1