快速幂&矩阵快速幂

求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;
}
posted @ 2022-02-08 19:37  dctwan  阅读(31)  评论(0编辑  收藏  举报