基础数论算法(八) 矩阵乘法与线性齐次递推公式的快速求值

矩阵乘法可是zhx钦定说考的可能性挺大的东西!


矩阵乘法

一个n*m的矩阵乘一个m*p的矩阵会得到一个n*p的矩阵。
因此有一道区间dp模板叫矩阵链乘法,不过这个不是重点。
矩阵乘法如果要简单的说,就是行乘每一列放在对应的行上。这么说可能不太清楚,不过我觉得代码比一堆 清晰的多。

void multi(int m,int n,int p){
    for(int i=0;ifor(int j=0;jfor(int k=0;k

特征根方程

为什么要提特征根方程?因为觉得很有趣如果解出来是整数说不定可以少些五行矩阵乘法。
对于f(n)=af(n-1)+bf(n-2)这种递推公式,我们可以用特征根方程求出通项。顺便一提,这种方法写大题的时候不能用,老老实实待定系数吧。
首先,把原通项写成f(n)-af(n-1)-bf(n-2)=0的形式。
接下来,解一个方程: x2axb=0 ,假设解为 x1,x2
那么我们称这两个解是这个数列的特征根。
这里要注意,如果无实数解,那么这个数列一般是具有周期性的。
如果 x1x2 ,那么 an=c1xn1+c2xn2 ,其中 c1,c2 带进去两个数就知道了。
例如:f(n)=2f(n-1)+3f(n-2),f(1)=5,f(2)=7
x22x3=0x1=3,x2=1
f(n)=3nc1+(1)nc2
{3c1c2=59c1+c2=7
解之得 c1=1,c2=2
f(n)=3n2(1)n ,要求的话带个快速幂美滋滋。
不过问题还是有的。一个是 x1=x2 的情况很糟心,一个是如果我们的特征根是无理数,而且要求一个很大的数取模,那么这种方法就会不适用。因此我们必须提出用矩阵乘法写的普适性更强的做法。


用矩阵乘法优化的线性齐次递推公式求值

首先我们来看一个神奇的东西。
对斐波那契数列,

(fn,fn1)(1110)=(fn+1,fn)

这样的话我们可以在常数时间内求出这个通项的下一项。而如果要求第n项,就相当于对这个矩阵进行幂运算。
有没有想到些什么?没错,见幂就开始快速幂。复杂度logn,比线性求不知道高到哪里去了。
那么能不能进一步推广?当然可以。
如果 f(n)=a1f(n1)+a2f(n2)+...+akf(nk)
那么显然,
(fn,fn1,...,fnk+1,fnk)a1a2...ak1ak10...0001...00...............00...0000...10=

(fn+1,fn,...,fnk+2,fnk+1)

是不是非常神奇?这样就可以用矩阵快速幂了。代码就不放了……

你可能感兴趣的:(数论)