快速幂&矩阵快速幂
求xn
朴素方法
遍历从1到n的所有数然后累乘即可
int simplePower(int x, int n){
int answer = 1;
for(int i = 1; i <= n; ++i){
answer *= i;
}
return answer;
}
时间复杂度为O(n)
快速幂
原理
xn
其中n = 2i + 2j + ... + 2k
一边求n的二进制一边根据每二进制位判断是否进行累乘,则时间复杂度为O(logn)
代码
int QuickPower(int x, int n){
int answer = 1;
while(n){
if(n % 2){ //根据当前n的最低二进制位继续判断是否需要累乘
answer *= x;
}
n /= 2; //n二进制右移
x *= x; //权重
}
return answer;
}
answer可能会溢出,可以通过取模运算,只获取xn最低k位,改进代码如下
int QuickPower(int x, int n, int k){
int answer = 1;
while(n){
if(n % 2){ //根据当前n的最低二进制位继续判断是否需要累乘
answer *= x;
answer %= k;
}
n /= 2; //n二进制右移
x *= x; //权重
x %= k;
}
return answer;
}
矩阵快速幂
矩阵定义
struct Matrix{
int data[MAXSIZE][MAXSIZE];
int row, col;
Matrix(int r, int c): row(r), col(c) {}
};
矩阵乘法
Matrix Mul(Matrix a, Matrix b){
Matrix answer = Matrix(a.row, b.col);
for(int i = 0; i < answer.row; ++i){
for(int j = 0; j < answer.col; ++j){
answer.data[i][j] = 0;
for(int k = 0; k < a.col; ++k){
answer.data[i][j] += a.data[i][k] * b.data[k][j];
}
}
}
return answer;
}
矩阵快速幂
Matrix QuickPowerMatrix(Matrix x, int n){
Matrix answer = Matrix(x.row, x.col);
//初始化单位矩阵
for(int i = 0; i < answer.row; ++i){
for(int j = 0; j < answer.col; ++j){
if(i == j){
answer.data[i][j] = 1;
}
else{
answer.data[i][j] = 0;
}
}
}
//快速幂在矩阵上的应用
while(n){
if(n % 2){
answer = Mul(answer, x);
}
n /= 2;
x = Mul(x, x);
}
return answer;
}