矩阵快速幂(学习)
两矩阵相乘,朴素算法的复杂度是O(N^3)。如果求一次矩阵的M次幂,按朴素的写法就是O(N^3*M)。既然是求幂,不免想到快速幂取模的算法,这里有快速幂取模的介绍,a^b %m 的复杂度可以降到O(logb)。如果矩阵相乘是不是也可以实现O(N^3 * logM)的时间复杂度呢?答案是肯定的。
先定义矩阵数据结构:
O(N^3)实现一次矩阵乘法
下面介绍一种特殊的矩阵:单位矩阵
![](http://pic002.cnblogs.com/images/2012/307740/2012040116092159.png)
很明显的可以推知,任何矩阵乘以单位矩阵,其值不改变。
有了前边的介绍,就可以实现矩阵的快速连乘了。
举个例子:
求第n个Fibonacci数模M的值。如果这个n非常大的话,普通的递推时间复杂度为O(n),这样的复杂度很有可能会挂掉。这里可以用矩阵做优化,复杂度可以降到O(logn * 2^3)
如图:
![](https://i-blog.csdnimg.cn/blog_migrate/20128bff6d62cab233d55e0f7fef1698.png)
A = F(n - 1), B = F(N - 2),这样使构造矩阵
的n次幂乘以初始矩阵
得到的结果就是
。
![](https://i-blog.csdnimg.cn/blog_migrate/8abe334e982051c558b6c6ffe0aa66ca.png)
![](https://i-blog.csdnimg.cn/blog_migrate/b1c4df9463f152a0a01b1b13fd1dcae4.png)
![](https://i-blog.csdnimg.cn/blog_migrate/84eb3598678f4ef33c4cb51c08a97af7.png)
因为是2*2的据称,所以一次相乘的时间复杂度是O(2^3),总的复杂度是O(logn * 2^3 + 2*2*1)。
zoj上的一道例题: zoj 2853 Evolution.
这道题都不用考虑怎么去构造能够实现有效运算的矩阵。直接修改单位矩阵就可以。比如P(i, j) = 0.5,则mat[i][j] += 0.5,mat[i][i] -= 0.5; 然后求T*mat^M,(T表示原始的population序列,相当于1*n的矩阵)
ps:这道题不加剪枝的话还是会挂掉 -_-!
最近正在学习和矩阵有关的算法,看到这篇关于快速矩阵幂的文章就转过来了。