题目
给定A, B, P,求(A^B) mod P。
输入
输入共一行。
第一行有三个数,N, M, P。
输出
输出共一行,表示所求。
共10组数据
对100%的数据,A, B为long long范围内的非负整数,P为int内的非负整数。
样例输入
2 5 3
样例输出
2
解题思路
本题数据很大,用传统方法肯定会超时,因此我们使用快速幂的方法。(类似题目:矩阵快速幂——题目 2311: 蓝桥杯2019年第十届省赛真题-Fibonacci 数列与黄金分割)
代码
#include<stdio.h>
#include<math.h>
int main()
{
long int A,B,P,t=1;
scanf("%ld %ld %ld",&A,&B,&P);
A%=P;
while (B!=0){
if (B&1==1)//末位为1
t*=A;
A*=A;
A%=P;
t%=P;//防止越界
B>>=1;//右移,表示除以2
}
printf("%ld",t);
return 0;
}
测试用例
(C语言网)部分测试用例如下:
测试输入 | 测试输出 |
---|---|
5627022903281636461 1158331967964984092 688850330 | 351401031 |
5 0 1000 | 1 |
6077632445545927759 7458966503284680976 1445658521 | 714763859 |
5843493273010459717 3410275051945425675 1441300821 | 448863514 |
8057993924663137522 6151631676926253056 1517806262 | 378572952 |
错误代码
用非递归快速幂的时候,还要注意使用2进制来进行次数的减少,我用10进制来表示次数,还是会导致较多的循环次数,如下代码所示,时间超限(45分):
#include<stdio.h>
#include<math.h>
int main()
{
long int A,B,P,temp,i=1,k=0,temp1,top,left;
scanf("%ld %ld %ld",&A,&B,&P);
A%=P;
temp = A;
temp1 = 1;
for (i=0;i<100;i++)
if (pow(2,i)>B)
break;
top = i;//次数上限
left = B-pow(2,i-1);
i = 1;
while (i<top){
temp*=temp;
temp%=P;
i++;//快速幂部分
if (k<left)
{
temp1*=A;
temp1%=P;
k++;
}
}
if (k!=left)
for (i=1;i<=(left-k);i++)
temp1*=A,temp1%=P;
if (B==0)
printf("1");
else
printf("%ld",(temp*temp1)%P);
return 0;
}