常系数线性递推关系的定义
对于满足
a n = ∑ i = 1 k c i a n − i + f ( n ) a_n=\sum_{i=1}^{k}c_ia_{n-i}+f(n) an=i=1∑kcian−i+f(n)
一类的递推关系(其中 c , k c,k c,k 为常数),我们称之为常系数线性递推关系。
只要给定 a 0 , a 1 , … , a k − 1 a_0,a_1,\dots,a_{k-1} a0,a1,…,ak−1 以及 c 1 , c 2 , … , c k c_1,c_2,\dots,c_k c1,c2,…,ck 以及 f ( n ) f(n) f(n) ,我们就能求出 a a a 的任意一项。
这个问题的一般形式是不能快速求解的,比如令 f ( n ) = ln n f(n)=\ln n f(n)=lnn 。但有一些特殊形式我们可以快速求解。我们先从齐次常系数线性递推关系来研究。
齐次常系数线性递推关系的求值
齐次常系数线性递推关系即 f ( n ) = 0 f(n)=0 f(n)=0 的情况,此时 a n = ∑ i = 1 k c i a n − i a_n=\sum_{i=1}^{k}c_ia_{n-i} an=∑i=1kcian−i 。
这看起来像线性变换,因此考虑从线性变换的角度解决这个问题。
矩阵优化
我们构造初始向量
x ⃗ = [ a k − 1 a k − 2 ⋮ a 1 a 0 ] \vec x= \left[ \begin{matrix} a_{k-1} \\ a_{k-2} \\ \vdots \\ a_1 \\ a_0 \\ \end{matrix} \right] x=⎣⎢⎢⎢⎢⎢⎡ak−1ak−2⋮a1a0⎦⎥⎥⎥⎥⎥⎤
以及转移矩阵
A = [ c 1 c 2 ⋯ c k − 2 c k − 1 c k 1 0 ⋯ 0 0 0 0 1 ⋯ 0 0 0 ⋮ ⋮ ⋱ ⋮ ⋮ ⋮ 0 0 ⋯ 1 0 0 0 0 ⋯ 0 1 0 ] A= \left[ \begin{matrix} c_1 &c_2 &\cdots &c_{k-2} &c_{k-1} & c_k\\ 1 & 0 &\cdots & 0 & 0 & 0 \\ 0 & 1 &\cdots & 0 & 0 & 0 \\ \vdots &\vdots & \ddots &\vdots &\vdots &\vdots \\ 0 & 0 &\cdots & 1 & 0 & 0 \\ 0 & 0 &\cdots & 0 & 1 & 0 \\ \end{matrix} \right] A=⎣⎢⎢⎢⎢⎢⎢⎢⎡c110⋮00c201⋮00⋯⋯⋯⋱⋯⋯ck−200⋮10ck−100⋮01ck00⋮00⎦⎥⎥⎥⎥⎥⎥⎥⎤
于是
A n ⋅ x ⃗ = [ a n + k − 1 a n + k − 2 ⋮ a n + 1 a n ] A^n\cdot \vec x= \left[ \begin{matrix} a_{n+k-1}\\ a_{n+k-2} \\ \vdots \\ a_{n+1}\\ a_n\\ \end{matrix} \right] An⋅x=⎣⎢⎢⎢⎢⎢⎡an+k−1an+k−2⋮an+1an⎦⎥⎥⎥⎥⎥⎤
这样我们就可以用矩阵快速幂来求 a n a_n an 了,复杂度 O ( k 3 log n ) O(k^3\log n) O(k3logn) 。
但这个复杂度依然不够优秀,考虑从线性代数的角度切入。
特征多项式优化
事实上,我们可以把 A n A^n An 表示为 A 0 , A 1 , ⋯   , A k − 1 A^0,A^1,\cdots,A^{k-1} A0,A1,⋯,Ak−1 的线性组合,并且我们有:
A n = ∑ i = 1 k c i A n − i A^{n}=\sum_{i=1}^{k} c_iA^{n-i} An=i=1∑kciAn−i
为什么呢?
我们可以从 C a y l a y − C a m i l t o n Caylay-Camilton Caylay−Camilton 定理1来考虑:
对于矩阵 A A A 的特征多项式 f ( λ ) = det ∣ λ I − A ∣ f( \lambda )=\det \left| \lambda I-A\right| f(λ)=det∣λI−A∣ ,我们有 f ( A ) = 0 f(A)=0 f(A)=0 。
而对于上述转移矩阵,我们有:
f ( λ ) = λ k − ∑ i = 1 k c i λ n − i f(\lambda)=\lambda ^k-\sum_{i=1}^{k}c_i \lambda ^{n-i} f(λ)=λk−i=1∑kciλn−i
将 A A A 代入上式即可。
当然我们也可以从其他角度考虑。
A n ⋅ x ⃗ = [ a n + k − 1 a n + k − 2 ⋮ a n + 1 a n ] A^{n}\cdot \vec x= \begin{bmatrix} a_{n+k-1}\\ a_{n+k-2} \\ \vdots \\ a_{n+1}\\ a_n\\ \end{bmatrix} An⋅x=⎣⎢⎢⎢⎢⎢⎡an+k−1an+k−2⋮an+1an⎦⎥⎥⎥⎥⎥⎤
∑ i = 1 k c i A n − i ⋅ x ⃗ = [ ∑ i = 1 k c i a n − i + k − 1 ∑ i = 1 k c i a n − i + k − 2 ⋮ ∑ i = 1 k c i a n − i + 1 ∑ i = 1 k c i a n − i ] = [ a n + k − 1 a n + k − 2 ⋮ a n + 1 a n ] = A n ⋅ x ⃗ \sum_{i=1}^{k} c_iA^{n-i}\cdot \vec x= \begin{bmatrix} \sum_{i=1}^kc_ia_{n-i+k-1}\\\\ \sum_{i=1}^kc_ia_{n-i+k-2}\\\\ \vdots \\\\ \sum_{i=1}^kc_ia_{n-i+1}\\\\ \sum_{i=1}^kc_ia_{n-i}\\\\ \end{bmatrix}= \begin{bmatrix} a_{n+k-1}\\\\ a_{n+k-2} \\\\ \vdots \\\\ a_{n+1}\\\\ a_n\\\\ \end{bmatrix}= A^{n}\cdot \vec x i=1∑