ACM - 算法 | 快速幂

快速幂

顾名思义,快速幂就是快速算底数的n次幂。其时间复杂度为 O(log₂N), 与朴素的O(N)相比效率有了极大的提高。

快速幂的思想

假设一个情况,我们要求 511 的具体值。利用常规思路,即为
5 ∗ 5 ∗ 5 ∗ 5 ∗ 5 ∗ 5 ∗ 5 ∗ 5 ∗ 5 ∗ 5 ∗ 5 = 48828125 5*5*5*5*5*5*5*5*5*5*5=48 828 125 55555555555=48828125这样的操作在算法内即通过一个循环可以完成,时间复杂度为 O ( n ) O(n) O(n)
但是,快速幂采用了一种更巧妙,且更快的思路。我们将 511 做如下变换

5 23 + 21 + 20


接下来我们首先设定 a n s = 1 , a = 5 ans=1,a=5 ans=1a=5 而后,我们看到 5 5 5 的幂中有 2 0 ( = 1 ) 2^0(=1) 20(=1),所以我们将 a n s = a n s ∗ a = 5 ans=ans*a=5 ans=ansa=5 ,之后将 a = a ∗ a = 5 2 = 25 a=a*a=5^2=25 a=aa=52=25,接下来我们发现 5 5 5 的幂中有 2 1 ( = 2 ) 2^1(=2) 21(=2),所以我们将 a n s = a n s ∗ a = 125 ans=ans*a=125 ans=ansa=125,之后将 a = a ∗ a = 5 4 = 625 a=a*a=5^4=625 a=aa=54=625,但是我们发现 5 5 5 的幂中没有 2 2 ( = 4 ) 2^2(=4) 22(=4),所以这一步不对 a n s ans ans 进行操作,直接将 a = a ∗ a = 390625 = 5 8 a=a*a=390625=5^8 a=aa=390625=58,接着我们发现 5 5 5 的幂中有 2 3 ( = 8 ) 2^3(=8) 23(=8),所以我们将 a n s = a n s ∗ a = 48828125 ans=ans*a=48828125 ans=ansa=48828125,得到了我们的答案。数一数,在上述过程中,一共经过了 6次运算 ,相较于原先的 11次运算 有了明显的改进,因为快速幂的思想就是将之前获得的值再次利用,避免重复计算,于是可以降低时间复杂度。

那么还有一个问题,如何快速实现 11 = 2 3 + 2 1 + 2 0 11=2^3+2^1+2^0 11=23+21+20的转变呢?,其实这里运用到了二进制和十进制的转换, 11 11 11 在二进制中为 1011 1011 1011,再运用二进制转十进制的想法我们就可以获得 2 3 + 2 1 + 2 0 2^3+2^1+2^0 23+21+20 这一式子,在计算机中,可以通过运算符>><<快速实现这一思想,以及上述的是否存在幂的比较过程,下面将在代码中体现。

代码

//由于快速幂后数值可能过大,所以往往伴随取模运算
ll mod = 10e9 + 7;
ll qpow(int a, int n) {
	ll re = 1;
	while (n) {
		if (n & 1) {
			re = (re*a) % mod;
		}
		n >>= 1;
		a = (a*a) % mod;
	}
	return re%mod;
}

快速幂的其他运用

逆元

这里转载一个博客:https://blog.sengxian.com/algorithms/mod-world
其对于模运算的总结以及其中涉及到的逆元十分详尽

逆元常常被运用于分数取模中,注意分数取模和整数是不同的,因为取模和取余的意义就有很大不同,但常常容易弄混,在了解了逆元后,对于分数取模的意义会有更加深刻的理解。

例题(HDU - 6595)http://acm.hdu.edu.cn/showproblem.php?pid=6595
当然此题的关键在于如何获得期望公式,而非取模。
这题在获得期望公式后,剩下的操作就是取模,在取模的过程中则会运用到快速幂来求解逆元,最后输出答案,由于是分数取模,所以可以看到样例中的两个输出都会有很大的值。

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值