矩阵快速幂引入:
1.整数快速幂:
为了引出矩阵的快速幂,以及说明快速幂算法的好处,我们可以先求整数的幂。
如果现在要算X^8:则 XXXXXXXX 按照寻常思路,一个一个往上面乘,则乘法运算进行7次。
(XX)(XX)(XX)(XX)
这种求法,先进行乘法得X^2,然后对X^2再执行三次乘法,这样去计算,则乘法运算执行4次。已经比七次要少。所以为了快速算的整数幂,就会考虑这种结合的思想。
现在要考虑应该怎么分让计算比较快。接下来计算整数快速幂。例如:X^19次方。
19的二进制为:1 0 0 1 1 。
由(X^m)(X^n) = X^(m+n)
则X^19 = (X^16)(X^2)*(X^1)
那么怎么来求解快速幂呢。请看下列代码:
求解X^N的值。
///整数快速幂,计算x^N
1 int QuickPow(int x,int N)//传入底数x和指数N 2 { 3 int res = x; 4 int ans = 1; 5 while(N) 6 { 7 if(N&1)//N是奇数 8 { 9 ans = ans * res; 10 } 11 res = res*res; 12 N = N>>1;//N向右移位 13 } 14 return ans;
}
那么让我们来看看下面这段代码到底对不对:
对于X^19来说:
19的二进制为:1 0 0 1 1
初始:
那么让我们来看看下面这段代码到底对不对:
对于X^19来说:
19的二进制为:1 0 0 1 1
初始:
ans = 1; res = x;
则10011最后一位是1,所以是奇数。
ans = res*ans = x; res = res*res = x^2;
然后右移一位,1 0 0 1
则1001最后一位是1,所以是奇数
ans = res*ans = x*(x^2) = x^3 res = res*res = x^2*x^2 = x^4
然后右移一位,1 0 0
则最后一位是0,所以当前的数为偶数。
res = res*res = x^4*x^4 = x^8
然后右移一位,1 0
最后一位是0,当前数是偶数。
res = res*res =x^8*x^8= x^16
然后右移一位,1
最后一位是1,当前数是奇数
ans = ans*res = (x^3)*(x^16) = x^19 res = res*res = x^32
2.矩阵快速幂算法篇
算法思想与整数快速幂算法类似:
1 struct Mat 2 { 3 LL m[101][101]; 4 };//存储结构体 5 Mat a,e; //a是输入的矩阵,e是输出的矩阵 6 Mat Mul(Mat x,Mat y) 7 { 8 Mat c; 9 for(int i=1;i<=n;++i){ 10 for(int j=1;j<=n;++j){ 11 c.m[i][j] = 0; 12 } 13 } 14 for(int i=1;i<=n;++i){ 15 for(int j=1;j<=n;++j){ 16 for(int k=1;k<=n;++k){ 17 c.m[i][j] = c.m[i][j]%mod + x.m[i][k]*y.m[k][j]%mod; 18 } 19 } 20 } 21 return c; 22 } 23 Mat pow(Mat x,LL y)//矩阵快速幂 24 { 25 Mat ans = e; 26 while(y){ 27 if(y&1) ans = Mul(ans,x); 28 x = Mul(x,x); 29 y>>=1; 30 } 31 return ans;