快速幂算法 Exponentiation by squaring

算法简述

一个自然数k可以写成$k=\sum_1^na_i*2^i,a_i\in\{0,1\}$的形式。快速幂的思想就基于此。 当一个式子为齐次线性递推式时,就可以把数列的递推关系转化为矩阵的递推关系,即构造出一个矩阵的n次方乘以一个列向量得到一个列向量,这个列向量中包含我们要求的 f(n)。 比如 $$ a^{21}=a^{(1*2^0+1*2^2+1*2^4)} =a^1*a^4*a^{16} $$

常见疑惑的说明:

代码实现

C++:(mod为要取模的数,无则删去)

double pow(double a,long long k)
{
    if(a==0)
        return 0;
    double ans=1;
    int NF=0;
    if(k<0)
    {
    	k=-k;
    	NF=1;
    }
    while(k)
    {
        if(k&1)
            ans=ans*a%mod;
        a=(a*a)%mod;//a=a^i%mod
        k>>=1;
    }
    if(NF)
    	return 1/ans;
    return ans;
}

矩阵快速幂

vector<vector<long long>> matrix_multiply(const vector<vector<long long>> &a,const vector<vector<long long>> &b) 
{
  	int r=a.size(),c=a[0].size();
    vector<vector<long long>> ans(r,vector<long long>(c));
    for(int i=0;i<r;i++) 
    {
        for(int j=0;j<c;j++)
            ans[i][j]=a[i][0]*b[0][j]+a[i][1]*b[1][j];
    }
    return ans;
}

vector<vector<long long>> matrixPow(vector<vector<long long>> a,int n) 
{
 	vector<vector<long long>> ret={{1,0},{0,1}};//initialize as you need
 	
    while(n>0) 
    {
        if(n&1)
            ret=matrix_multiply(ret,a);
        n>>=1;
        a=matrix_multiply(a,a);
    }
    return ret;
}


时间复杂度 空间复杂度 补充说明 适用范围
快速幂 \(O(log(n))\) 无
矩阵快速幂 \(O(log(n))\) 无

例题:
力扣743网络延迟时间 https://leetcode-cn.com/problems/network-delay-time/