题目大意:给定n阶方阵A,计算S = A^1+A^2+……+A^k
(mod m) (k <= 10^9)
我们可以根据矩阵快速幂在O(n^3log(k))的时间里算出A^k,但我们也不能一个一个算再加起来啊,那样铁定超时……
①二分
这种方法我觉得与
秦九韶算法计算多项式的思路类似,都是找出重复因子而减少多项式计算的次数.当然我们这个多项式比较特殊,所以有比秦九韶算法更好的思路:
当k为偶数时:
S(k) = A^1+A^2+A^3 + A^(k/2) + A^(k/2+1) + …… + A^(k/2+k/2)
= (A^(k/2) + E) (A^1 + A^2 + A^3 …… + A^(k/2) )
=(A^(k/2) + E) * S(k/2)
当k为奇数时:
S(k) = S(k-1) * A^k
这种方法可能出现递归过深的问题,所以要设置好占空间小心栈溢出,而且速度也偏慢
11217405 |
AbandonZHANG |
3233 |
Accepted |
3532K |
704MS |
G++ |
2444B |
2013-01-28 20:53:36 |
#include
#include
#include
#include
#include
#include
#include
#include
#include
②线性变换(很赞的一种方法呐~!涨姿势~)
我们考虑递推,即从s(k-1)到s(k)的线性变换。
首先一维线性变换显然是出不来的,就像A^1+A^2+A^3+……+A^k = d * (A^1+A^2+A^3+……+A^(k-1) ) 明显不行……
那么我们再加一维就显然了:
A^1+A^2+A^3+……+A^k =( A^1+A^2+A^3+……+A^(k-1) ) + A^k
A^(k+1) = 0 * ( A^1+A^2+A^3+……+A^(k-1) ) + A * A^k. //这一行的变换是作为辅助,补全二维的线性变换.
那么线性变换矩阵B显然就是:
1 1
0 1
一般化就有
s(k) 1 1 s(k-1)
A^k+1 = 0 1 * A^k
即P(k) = B^(n-1) * P(1)
这样要比①好多了,又省空间又省时间。
11217490 |
AbandonZHANG |
3233 |
Accepted |
1016K |
282MS |
G++ |
2962B |
2013-01-28 21:25:37 |
#include
#include
#include
#include
#include
#include
#include
#include
#include