芝士:线性齐次递推
背景
给定数列h的前k项,其后第n项满足\(\sum_{i=1}^{k}a_ih_{n-i+1}\),求第n项
很容易得到的是一个矩阵快速幂的解法\(O(k^3*log_n)\)
但是某些大犇表示对于某些特定的数列可以更快
特征值&特征向量
有常数\(\lambda\),和矩阵A,向量\(\vec{a}\)
满足\(A*\vec a=\lambda*\vec a\)
则向量\(\vec a\)成为A的特征向量,\(\lambda\)为A的特征值
过程
矩阵快速幂的时间复杂度集中在求\(A^n\)上,所以我们考虑对其优化
我们模仿矩阵快速幂的过程
\(\begin{bmatrix}h_k\\h_{k-1}\\.\\.\\.\\h_1\end{bmatrix}*\begin{bmatrix}a_1,a_2,\cdots,a_k\\1,0,\cdots,0\\0,1,\cdots,0\\.\\.\\0,0,\cdots,1\end{bmatrix}=\begin{bmatrix}h_{k+1}\\h_k\\.\\.\\.\\h_2\end{bmatrix}\)
注意这里的\(h_1\)只是中途的某一个向量的第这一项,与数列h中的\(h_1\)无关
因为有\(\lambda\)的存在
所以有
\(\begin{bmatrix}h_k\\h_{k-1}\\.\\.\\.\\h_1\end{bmatrix}*\lambda=\begin{bmatrix}h_{k+1}\\h_k\\.\\.\\.\\h_2\end{bmatrix}=\begin{bmatrix}\lambda*h_k\\\lambda*h_{k-1}\\.\\.\\.\\\lambda*h_1\end{bmatrix}\)
\(h_2=\lambda h_1\)
\(h_3=\lambda h_2=\lambda^2h_1\)
\(h_{k+1}=\lambda^{k}h_1\)
然后我们又知道
\(h_{k+1}=\sum_{i=1}^{k}a_ih_{k-i+1}\)
联立可得
\(\lambda^kh1=\sum_{i=1}^{k}a_ih_{k-i+1}=\sum_{i=1}^{k}a_i\lambda^{k-i}h_1\)
之后就是
\(\lambda^kh_1-\sum_{i=1}^{k}a_i\lambda^{k-i}h_1=0\)
\(\lambda^kh_1-a_1\lambda^{k-1}h_1-\cdots-a_kh_1=0\)
\(\lambda^k-a_1\lambda^{k-1}-\cdots-a_k=0\)
这就是一个k次的方程,\(\lambda\)就是这个方程的解,当然对于不同的\(h_1\),\(\lambda\)不同,但是那无所谓啊,我们只需要 \(\lambda\)存在就行了
我们用\(F(x)=x^k-\sum_{i=1}^{k}a_ix^{k-i}\)
肯定可以有函数\(G(x)\)和函数\(R(x)\),满足
\(x^n=F(x)*G(x)+R(x)\)
这里的n是数列第n项
下面到了我们所喜爱(伤肝)的多项式环节
这样我们就可以将\(R(x)\)所求出
根据Cayley-Hamilton定理所说的@¥!@#&*#@!
可以得到\(F(A)=0\),这里的A是矩阵A
所以\(A^n=R(A)\),
时间复杂度为\(O(k^4)\)
等等,作者你是不是在逗我?矩阵快速幂都比这快,我们要这有用?(举起菜刀)
不不不,我们调换一下顺序
\(\vec a*A^n=\vec a*R(A)=\vec a*\sum_{i=0}^{k-1}r_iA^i=\sum_{i=0}^{k-1}\vec ar_iA^i\)
一个向量乘上一个矩阵,时间复杂度为\(O(k^2)\),所以总时间复杂度为\(O(k^3)\)
但这样就是这个方法的极限了么?不
我们先不考虑\(r_i\)
我们考虑\(\vec a*A\),是什么,不就是将\(\vec a\)上移?
即
\(\begin{bmatrix}a_k\\a_{k-1}\\\vdots\\a_1\end{bmatrix}\rightarrow\begin{bmatrix}a_{k+1}\\a_k\\\vdots\\a_2\end{bmatrix}\)
虽然我们\(\sum_{i=0}^{k-1}\vec aA^i\)会得到k个向量,但是这k个向量不同的元素之后2k个
我们暴力将前2k个求出来,时间复杂度为\(O(k^2)\),再将其填回去,顺便将答案求出,时间复杂度为\(O(k^2)\),
但是,多项式的除法时间复杂度为多少?n太大了,根本存不下,我们只能边快速幂边取模,
时间复杂度为\(O(max(k^2,k*log_k*log_n))\)