快速幂:快速幂是一种十分快速的解决幂运算的方法。能把时间复杂度从n降到logn。十分高效的算法。大致思路是这样的16 = 2 * 2 * 2 * 2.是四个2相乘。我们计算时可以把2两两结合 就变成16 = (2 * 2) * (2 * 2)= 4 * 4 变成了两个4相乘。.这样就降低了运算的次数。如果是32 = 2 * 2 * 2 * 2 * 2当相乘的个数为5个 ,为奇数时。没有办法两两结合,我们可以把他单独拉出计算。
实现代码如下:
int quick_pow(int a,int b){
int ret = 1;
while(b){
if(b&1) ret = ret * a;
a = a * a;
b >>= 1;
}
return ret;
}
其中牵扯到一点二进制运算。如b&1 是判断b为奇数还是偶数。 b>>=1 是b/2的意思。
要讲矩阵快速幂。那必须先说一说什么是矩阵。但是矩阵又不是这个重点,我就简述一下矩阵的运算把。
简单的说矩阵就是二维数组,数存在里面,矩阵乘法的规则:A*B=C
其中c[i][j]为A的第i行与B的第j列对应乘积的和,即:。
公式很简单。简单一句话就是,新矩阵的第I行第j列 是第一个矩阵的i行的每一个元素乘上另一个矩阵的j列每一个元素的总和。
矩阵快速幂:当多相同个矩阵相乘时和数字的幂运算差不多。也可以用矩阵来优化这个运算次数,代码如下:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 110;
const int mod = 1e9+7;
int n;
struct mat{
int m[maxn][maxn];
}unit;
mat operator * (mat a,mat b){
mat ret ;
ll x;
for(int i =0 ; i < n ; i++){
for(int j = 0 ; j < n ; j++){
x = 0 ;
for(int k = 0 ; k < n ; k ++)
x += ((ll)a.m[i][k] * (ll)b.m[k][j]) % mod;
ret.m[i][j] = x % mod;
}
}
return ret;
}
void init_unit(){
for(int i = 0 ; i < maxn ; i ++)
unit.m[i][i] = 1;
return ;
}
mat pow_unit(mat a,ll n){
mat ret = unit;
while(n){
if(n&1) ret = ret*a ;
a = a * a;
n >>= 1;
}
return ret;
}
int main(){
ll x;
init_unit();
while(cin >> n >> x){
mat a;
for(int i = 0 ; i < n ; i ++){
for(int j = 0; j < n ;j ++)
cin >> a.m[i][j];
}
a = pow_unit(a,x);
for(int i = 0 ; i < n ; i ++){
for(int j = 0 ; j < n ; j ++){
if( j + 1 == n) cout << a.m[i][j] << endl;
else cout <<a.m[i][j] <<" ";
}
}
}
return 0;
}
如果理解快速幂,那么理解矩阵快速幂也非常容易,但是快速幂的应用不止如此。这只是模板介绍。