矩阵快速幂-QuickPow

矩阵快速幂引入:


  1.整数快速幂:

  为了引出矩阵的快速幂,以及说明快速幂算法的好处,我们可以先求整数的幂。
如果现在要算X^8:则 XXXXXXXX 按照寻常思路,一个一个往上面乘,则乘法运算进行7次。
(X
X)(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;
View Code
原文地址:https://www.cnblogs.com/DengSchoo/p/Algorithm-01-MatrixQuickPow.html