题目 2088: 蓝桥杯算法提高VIP-快速幂

题目

给定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 688850330351401031
5 0 10001
6077632445545927759 7458966503284680976 1445658521714763859
5843493273010459717 3410275051945425675 1441300821448863514
8057993924663137522 6151631676926253056 1517806262378572952

错误代码

用非递归快速幂的时候,还要注意使用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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值