常系数齐次线性递推算法学习

简介

定义:设有数列{an}an=i=1kanifi\{a_n\}满足递推关系a_n=\sum\limits_{i=1}^{k}a_{n-i}f_i,则称该数列满足kk阶齐次线性递推关系。

求法

现在我们从最基础的矩阵快速幂开始一步一步优化求ana_n的时间复杂度。

矩阵快速幂

直接上矩阵快速幂来优化递推即可,时间复杂度为O(k3logn)O(k^3log_n),非常不优秀,因此我们考虑用更快的方法求出ana_n

在我们知道了a1,a2,...aka_1,a_2,...a_k之后想推出ana_n的方法可以借鉴矩阵快速幂的方法,构造一个kkk*k的矩阵MM来完成递推,关键就是优化求MnM^n的时间复杂度了,这里我们引入一个叫做特征多项式的东西。

特征多项式

一些定义

特征值,特征向量A,λvλv=Av对于一个矩阵A,若\exist常数\lambda和向量\vec v满足\lambda\vec v=A\vec v则称向量v\vec v为矩阵AA的一组特征向量,λ\lambda为矩阵AA的一组特征值。
特征多项式,特征方程,特征值:我们对上面的关系式进行变换:(λEA)v=0(\lambda E-A)\vec v=0,学过线性代数的都知道这个方程有解的充要条件是det(λEA)=0det(\lambda E-A)=0,于是我们将det(λEA)det(\lambda E-A)看成一个kk次多项式f(x)f(x),我们将f(x)=0f(x)=0这个方程称作特征方程,将f(x)f(x)称作特征多项式,而特征方程的kk个根就是kk个特征值。
由于一共有kk个解,因此我们可以换一种形式来表示f(x)f(x)f(x)=i=1k(xλi),λiiif(x)=\prod_{i=1}^k(x-\lambda_i),\lambda_i指第i个特征值即第i个解

Cayley-Hamilton定理

这是特征根多项式的一个重要性质,叙述如下:
AA是数域PP上的NN阶矩阵,其特征多项式f(λ)=λEA=λN+b1λN1+b2λN2+...+bN1λ+bNf(λ)=|λE−A|=λ^N+b_1λ^{N−1}+b_2λ^{N−2}+...+b_{N−1}λ+b_N
f(A)=AN+b1AN1+b2AN2+...+bN1A+bN=Of(A)=A^N+b_1A^{N−1}+b_2A^{N−2}+...+b_{N−1}A+b_N=O,即f(λ)f(λ)为化零多项式。

递推优化

考虑MM的特征多项式f(x)f(x),这是一个kk次多项式。
不妨对MnM^nf(M)f(M)做一个多项式除法,令Mn=f(M)g(M)+r(M)M^n=f(M)g(M)+r(M),考虑到f(x)f(x)MM的特征多项式,因此f(M)=Or(M)=Mnf(M)=O\Rightarrow r(M)=M^n,于是问题转化成了求Mn%f(M)M^n\%f(M),并且我们已知这个多项式次数最多是k1k-1
然后就只用求出f(M)f(M)即可。
推导过程摘自DZYODZYO的博客
常系数齐次线性递推算法学习
常系数齐次线性递推算法学习
求出来之后对多项式取模即可。
直接O(k2)O(k^2)取模总时间复杂度是O(k2logn)O(k^2log_n)的。
当然可以更加毒瘤,我们用FFT来优化把总时间复杂度降到O(klogklogn)O(klog_klog_n)