【算法】快速幂取余

基本思想

对一个数进行指数运算的情况并不少见,如果在竞赛中遇到需要作出此类处理的时候,大多都会伴随着如下两个方面的问题:

1、数据范围
2、效率

针对这些,快速幂算法是个不错的选择。

进行指数运算的时候,大多会伴随着取余处理,于是针对第一个问题,我们不难想到如下的处理(以a^b为例子,对mod取余):

int ans = 1;
for(int i = 0;i < b;i++)
	ans = (ans*a)%mod;

把a的b次方拆分成b个a的乘积,同时在每次相乘后取余,这样就能保证得出的结果始终保持在一个可以直接存入基本数据类型的范围内,但是这样的处理在时间复杂度上又犯难了,为O(n)。

还得再进行一下处理,那么,既然a可以进行拆分,我们为什么不试着把b也拆开呢?

顺着这个思路,ab就可以变成(a*a)(b/2),以2^6为例:

2^6 = 4^3

然后再结合之前的拆分方法,就是快速幂取余了。

当然,还有一点需要注意,即b为奇数的时候,此时将b的值减1继续按照上述的方法运算即可,但是要在最终结果中乘上减去的这一次


实现代码

如下:

	
	int ans = 1;
	while(b > 0){
		if((b&1) == 1)
			ans = ans*a%mod;
		b >>= 1;
		a = (a*a)%mod;
	}
	return ans;

同时,为了进一步提升效率,算法中用到的奇偶判断以及除以2,可以全部使用位运算/doge

猜你喜欢

转载自blog.csdn.net/Jourofant/article/details/107496334