前言
感谢访问。
一、题目要求
题目描述:
求 a 的 b 次方对 p 取模的值,其中 0 <= a,b,p <= 10^9
输入要求:
三个用空格隔开的整数a,b和p。
输出要求:
一个整数,表示a^b mod p的值。
二、题解思路
1.预备知识:求余公式
2.思路
1.如果先求出a的b次方,时间复杂度为O(n),故采用快速幂,时间复杂度为O(log₂N)。
2.a的b次方%p:中心思想还是要有b个a相乘
如何凑出b个a?
将b表示为二进制,将值为1的位其权重值相加即为b
3.详细解释:b每右移一位,相当于除2。则需要进行a=a*a%p操作,根据求余公式,右移一次,该形式中含有两个a,第二次含有四个a,第三次含有8个a······
二进制表示形式例:13 = 1 * (2^3) + 1 * (2^2) + 0 * (2^ 1) + 1 * (2^0)
权重从0到2、4、8······,每一位的值或0或1。
右移一次,最后一位权重原为2,右移两次,最后一位权重原为4······
可以看出,在b右移的过程中,a的个数对应此时b的最后一位在移位前的权重。所以若该位值为1,则将a代入最终的求余结果中进行运算。
4.补充说明:最后结果还要t%p,是因为特殊例子。
例如:a=1,b=0,p=1,则最后应为0。
若不用t%p,而直接 t 则结果错。
原码如下(来自牛客):
#include<stdio.h>
int main()
{
long long int a,b,p;
long long int t=1;
scanf("%lld%lld%lld",&a,&b,&p); //%lld是long long int型
while(b)
{
if(b&1) //和1做与运算,最后一位的值为1,则结果为1
t=t*a%p;
b=b/2
a=a*a%p;
}
printf("%lld",t%p);
return 0;
}
总结
Stay hungry. Stay foolish.