一、快速幂
算法思想或步骤:
将阶数b转换为二进制,从后往前取每一位,如果是1就改变res, 其中,res表示有选择的乘以底数a的自乘(a, a^2 , a^4, a^8,......)。第1次,第2次,第3次,第4次....判断b的末尾位是否为1,为1就res=res*a,否则res不变;而a始终在自乘变化。最后返回res%mod,就是 (a^b)%mod.
代码:
long long ksm(long long a,long long b,int mod)
{
long long res=1;
while(b){
if(b&1) res=(res*a)%mod;//b的最后一位为1,改变res
a=(a*a)%mod;//a自乘
b>>=1;//b右移一位,上一位变成最后一位
}
return res%mod;
}
时间复杂度:O(log2n)
二、矩阵快速幂
算法思想或步骤:
思想同上,只不过涉及了线代中矩阵乘法的操作(注意矩阵必须是方阵)
代码:
struct Mat
{long long m[MAXN][MAXN];};//矩阵结构体
Mat Mul(Mat a,Mat b,int n,int mod)//矩阵乘法
{
Mat c;//存储结果的矩阵
memset(c.m,0,sizeof(c.m));//清空C
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
for(int k=1;k<=n;k++)
c.m[i][j]=(c.m[i][j]+(a.m[i][k]*b.m[k][j])%mod)%mod
return c;
}
Mat ksm_Mat(Mat a,long long b,int n,int mod)//矩阵快速幂
{
Mat res;
for(int i=1;i<=n;i++) //构建单位矩阵,类似于上面的res=1;
res.m[i][i]=1;
while(b){
if(b&1) res=Mul(res,a,n,mod);//b的最后一位为1,改变res
a=Mul(a,a,n);//矩阵a自乘
b>>=1;//b右移一位
}
return res;
}