问题引入
给出数列,满足当时
当时,
m比较小,n特别大,快速计算
Newbie的解法
暴力递推计算
时间复杂度
Pupil的解法
可以将转移和数列都写成的矩阵的形式,矩阵快速幂即可
时间复杂度
Master的解法
我们需要一些数学知识进行铺垫:
Part 1 矩阵的特征值与特征多项式
我们知道一个矩阵乘一个列向量仍然是一个列向量。
若对于m阶矩阵A,有常数,非零列向量,满足则称为矩阵A的特征值,为矩阵的特征向量
上式也可以写作其中为单位矩阵
此式有解的充要条件是,即矩阵的行列式为0
可以看做是关于的一个m次多项式,记作,称作矩阵A的特征多项式,对于矩阵A的任意一个特征值,都有。
Part 2 Hamilton-Cayley theorem
对于矩阵,也一样的定义多项式运算(把多项式中的x换乘矩阵A),加法就是直接对应相加,常数乘法就按位相乘,乘法是矩阵乘法,0次方是单位矩阵,它的结果仍然是一个矩阵。
显然,矩阵多项式满足交换律,即成立。
简单证明:考虑某两项相乘的结果,由于前后都是A,矩阵乘法满足结合律,因此指数可以任意分配,换成也是可以的
哈密顿—凯莱定理:对于矩阵A的特征多项式,满足
证明网上到处都有,此处就不赘述了。
Part 3 求解转移矩阵的特征多项式
回到原题,我们对于Pupil解法的转移矩阵A,求解它的特征多项式
考虑矩阵
它长这样:
根据行列式的定义,将第一行展开
其中表示矩阵A的代数余子式,即挖掉第i行和第j列以后剩下的矩阵的行列式。
我们发现所有的余子矩阵都是下三角矩阵,行列式就是对角线乘积。
化简整理,可得
负号都被行列式里面逆序对个数的负号消掉了。
Part 4 计算答案
我们设要求的数列的初始矩阵为,它是一个m行1列的矩阵(列向量),从第m行到第1行分别为(注意顺序是反的)
实际上我们想知道的就是矩阵的第m行第一列的值。
此时的关键就是,因为非常大,无法直接计算
然而根据前面的铺垫,我们有,我们可以看做只有一项的一个关于A的多项式
那么根据多项式除法相关知识,可以得到,其中的次数是小于的次数也就是小于m的,相当于多项式对多项式取模
可能会有这样的疑问,怎么能作除数呢?
其实并不要紧,我们并不需要知道的实际值,我们相当于将减去了若干个,将次数降低了,而结果不变。
实现上来说,由于的系数已知,我们可以先将式子里的矩阵A换成变量,代入,利用多项式取模算出Q的系数,然后再将x换回A,这样得出来的Q的系数是相同的。并且计算与的结果是一样的。
为了求出的系数,我们可以采用快速幂的做法,初始,然后不断的自己与自己相乘,乘完对多项式取模
这一部分如果暴力取模,时间复杂度为
如果采用NTT优化多项式取模,时间复杂度为
这样求出了的系数,不妨设
要求矩阵的第m行第一列的值
也就是的第m行第一列
然而的第m行第一列的值就是
所以
还有一种情况,前m项并没有直接给出,也是通过递推得出的,暴力递推求前m项的复杂度是的
考虑优化
考虑数列的一般生成函数(与矩阵G不同)
转移序列的一般生成函数
由于是无限长的一个序列,我们可以得到
其中是一个常数,相当于第0项
移项,可以得到
在模意义下多项式求逆即可
时间复杂度是的
模板题([BZOJ4161] Shlw loves matrixI)
Code