快速幂算法 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/