算法笔记之快速幂

快速幂简介:

快速幂基于二分的思想,常被称为二分幂。快速幂基于两个事实:

①若b为奇数,则a^b = a * a^(b-1)。

②若b为偶数,则a^b = a^(b/2) * a^(b/2)。

问题引入:

给定三个正整数a、b、m(a<10^9, b<10^6, 1<m<10^9 ),求a^b%m的值。

typedef long long LL;
LLpow(LL a, LL b, LL m){
	LL ans = 1;
	for(int i = 0; i < b ; i++){
		ans = ans * a % m;
	}
	return ans;
}//时间复杂度O(b)

若给定三个正整数a、b、m(a<10^9, b<10^18, 1<m<10^9 ),求a^b%m的值。

对于这个问题,再使用上面的方法就不可以了,O(b)的时间复杂度无法支持10^18。因此来到了快速幂的高光时刻!!!

快速幂递归写法代码实现:

typedef long long LL;
LLbinaryPow(LL a, LL b, LL m){
	if (b == 0)
		return 1;  //a^0=1
	if(b & 1)  //b为奇数,转换为b-1
		return a * binaryPow(a, b-1, m) % m;
	else{  //b为偶数,转换为b/2
		LL ans = binaryPow(a, b/2, m);
		return ans * ans % m;
	}
}//时间复杂度O(logb)

针对不同的题目,需要注意两个方面

①如果初始时a有可能大于等于m,就需要在进入函数前让a对m取模。

②如果m为1,可以直接在函数外部判定为0,不需要进入函数进行计算(任意正整数对1取模等于0)。

关于快速幂的迭代写法:

对a来说,如果把b写成二进制,b就可以写成若干二次幂的和。例如13的二进制是1101,3号位、2号位、0号位都是1,那么就可以得到13=2^3 +2^2 +2^0=8+4+1,所以 a^13 =a^(8+4+1)= a^8 * a^4 * a^1。

因此可得快速幂迭代写法的一般思路

①初始化令ans=1,存放累积的结果。

②判断b的二进制末尾是否为1 (也就是判断b是否为奇数),如果是,则令ans乘上a的值。

③令a平方,并将b右移一位(也就是将b除以2)。

④只要b大于0,就返回②。

快速幂迭代写法代码实现:

typedef long long LL;
LLbinaryPow(LL a, LL b, LL m){
	LL ans = 1;
	while(b > 0){
		if(b & 1) { //b为奇数
			ans = ans * a % m;  //令ans乘上a的值
		}
		a = a * a % m;  //令a平方
		b >>= 1;  //将b的二进制右移1位
	}
	return ans;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值