算法进阶——例题

移位运算例题

求 a 的 b 次方对 p 取模的值 , 其中 1 ≤ a , b , p ≤ 1 0 9 求a的b次方对p取模的值,其中1 \le a,b,p \le 10^9 ab次方对p取模的值,其中1a,b,p109

思路

根据数学常识,每个正整数可以唯一标识为若干指数不重复的 2 2 2的次幂的和。
也就是说,如果 b b b在二进制表示下有 k k k位,其中第 i ( 0 ≤ i < k ) i(0\le i<k) i(0i<k)位的数字时 c i c_i ci,那么:
b = c k − 1 2 k − 1 + c k − 2 2 k − 2 + ⋯ + c 0 2 0 b=c_{k-1}2^{k-1}+c_{k-2}2^{k-2}+\cdots+c_02^0 b=ck12k1+ck22k2++c020
于是
a b = a c k − 1 ∗ 2 k − 1 + a c k − 2 ∗ 2 k − 2 + ⋯ + a c 0 2 0 a^b=a^{c_{k-1}*2^{k-1}}+a^{c_{k-2}*2^{k-2}}+\cdots+a^{c_02^0} ab=ack12k1+ack22k2++ac020
因为 k = [ l o n g 2 ( b + 1 ) ] k=[long_2(b+1)] k=[long2(b+1)](其中[ ]表示向上取整),所以上市乘积项的数量不多于 [ l o g 2 ( b + 1 ) ] [log_2(b+1)] [log2(b+1)]个。又因为
a 2 i = ( a 2 i − 1 ) 2 a^{2 ^ i}=(a^{2^{i-1}})^2 a2i=(a2i1)2
所以我们很容易通过 k k k次递推求出每个乘积项,当 c i = 1 c_i=1 ci=1时,把该乘积项累积到答案中。 b & 1 b\&1 b&1运算可以取出 b b b在二进制下的最低位,而 b > > 1 b>>1 b>>1运算可以舍去最低位,在递推的过程中将二者结合,就可以遍历 b b b在二进制表示下的所有数位 c i c_i ci。整个算法的时间复杂度为 O ( log ⁡ 2 b ) O( \log _2b) O(log2b)

代码

	//calculate (a^b)modp
	int power(int a, int b, int p)
	{
		int ans = 1%p;
		for(;b;b>>=1)
		{
			if(b&1)
				ans = (long long)ans*a%p;
			a = (long long)a*a%p;
		}
		return ans;
	}

注意

若变量超出longlong的存储类型时,可以参考以下解决办法算法进阶——64位整数乘法

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

栖林_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值