相信大家对于矩阵快速幂都有一定的了解。大家也就知道快速幂对于幂运算的迅速,但是当出现了这样的问题:
我们就会发现即便矩阵快速幂再快,我们计算和我们都是O(n)的算法。那么在这个问题上,我们研究问题的重心就从矩阵的幂,转化为了矩阵幂的和。光看这个好像也想不出什么,那么我们换一个角度来思考这个问题。我们现在是要让计算变得更快,对吧?那么怎么样才能变得更快呢?时间复杂度的定义,就是从运算的次数来衡量时间的吧。那么现在我们就有目标了。我们要怎么减少运算的次数呢?显然就是尽量避免重复计算,换而言之就是尽可能的找出公共部分。于是我们很容易的得到下列式子:
现在我们发现公共部分,我们已经找到了,提取公因式:
同理我们还可以继续对式子后半部分(A^1 + A^2 + … + A^(n/2) )做相同的处理,于是我们惊奇的发现,我们将O(n)的复杂度降低为 O(log n)的时间复杂度了。
以下是代码实现:
//Matrix 类,同矩阵快速幂的Matrix类
//倍增法求解a^1 + a^2 + ... + a^n
Matrix slove(const Matrix &a, int n){
//递归终点
if(n == 1) return a;
//temp 递归表示a^1 + a^2 + ... + a^(n/2)
Matrix temp = slove(a, n/2);
//sum 表示 a^1 + a^2 + ... + a^(n/2) + (a^(n/2))*(a^1 + a^2 + ... + a^(n/2))
Matrix sum = temp + temp*a.pow(n/2);
//如果当n为奇数,我们会发现我们的(n/2 + n/2) == n-1
//于是我们需要补上一项: a^n
if(n & 1) sum = sum + a.pow(n);
return sum;
}
还有一种计算矩阵连乘求和
矩阵连乘求和:1 + A^2 + A^3 + … + A^n
1. 构造矩阵
|A 1|
|0 1|
例如求矩阵
|2 1|
|3 4|
的1 + A^2 + A^3 + … + A^n可以把矩阵构造成
|2 1 1|
|3 4 1|
|0 0 1|
结果为
7 6 4
18 19 8
0 0 1
结果的的第一行的全部相加结果就是1 + A^2 + A^3 + … + A^n的每一个A的i次幂的矩阵的第一行的和