快速幂
先来讨论整数的快速幂算法,相比于一般的计算a^b时间复杂度O(n),快速幂的复杂度是O(logn),效率要更高。比如要计算x^19,19的二进制表示是10011,分别找到二进制1出现的位置对应的数值,1,2,16。而19也正好可以写成1+2+16,所以x ^ 19 == (x ^ 1) *(x ^ 2) *(x ^ 16)。要找1出现的位置,可以依次移位判断。代码如下,可以一步步演算来验证一下:
1 int quickPow(int a, int b) //a^b 2 { 3 int ans = 1; 4 while(b) 5 { 6 if(b & 1) 7 ans *= a; 8 a *= a; 9 b >>= 1; 10 } 11 return ans; 12 }
矩阵快速幂
将快速幂的概念推广到矩阵,矩阵的幂运算首先是矩阵乘法,要满足第一个矩阵的列数等于第二个矩阵的行数,推广到幂,即满足方阵。
矩阵快速幂的重点在于T矩阵的构造,A(n) = T * A(n-1)。具体应用还需要具体分析
1 const int maxn = 2; 2 const int mod = 1e5 + 10; 3 4 //矩阵存储结构 5 struct Matrix 6 { 7 int mat[maxn][maxn]; 8 }; 9 10 //矩阵乘法 11 Matrix operator * (Matrix a, Matrix b) 12 { 13 Matrix ans; 14 //memset(ans.mat, 0, sizeof(ans.mat)); 15 fill(ans.mat[0], ans.mat[0] + maxn * maxn, 0); 16 for(int i = 0; i < maxn; i++) 17 { 18 for(int j = 0; j < maxn; j++) 19 { 20 for(int k = 0; k < maxn; k++) 21 { 22 ans.mat[i][j] += a.mat[i][k] * b.mat[k][j]; 23 ans.mat[i][j] %= mod; 24 } 25 } 26 } 27 return ans; 28 } 29 30 //矩阵快速幂 31 Matrix operator ^ (Matrix a, int n) 32 { 33 Matrix ans; 34 //初始化为单位矩阵 35 for(int i = 0; i < maxn; i++) 36 { 37 for(int j = 0; j < maxn; j++) 38 { 39 ans.mat[i][j] = (i == j); 40 } 41 } 42 while(n) 43 { 44 if(n & 1) 45 ans = ans * a; 46 a = a * a; 47 n >>= 1; 48 } 49 return ans; 50 }