快速幂+矩阵快速幂【模板】

一、快速幂

算法思想或步骤:

将阶数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;
}
posted @ 2021-04-26 16:20  unravel_CAT  阅读(66)  评论(0编辑  收藏  举报