给你3个数a,b,p。让你求a的b次方%p。
题目链接:【模板】快速幂||取余运算 - 洛谷
那么,我们该怎么来做这道题呢?
首先,我们想到的是用b个循环,每次让a乘上它自己。代码如下:
int a,b,p;
scanf("%lld%lld%lld",&a,&b,&p);
int x=a,y=b,m=p;
int ans=1;
for(int i=1; i<=b; i++){
ans=ans*a;
ans=ans%p;
}
printf("%lld^%lld mod %lld=%lld\n",x,y,m,ans);
这么写,是暴力的写法,只能拿到60分。
那么,还有什么方法呢?
快速幂!
首先,我们先来理解一下。
如果b是偶数,那么,如果说我们想要让b除以2,a该怎么处理呢?
举个栗子
=5*5*5*5*5*5
这个都能理解
那么=5*5*5*5*5*5呢?
然后,我们发现,这里有6个5。我们可以把变成
。
也就是25*25*25,结果是相等的。
我们发现,可以让a先乘它自己,把b除以2,就可以下一步了。
但是,如果b不是偶数,那么现在的25就不是一个整数。该怎么办呢?
那么,我们就可以把b减去1,让答案先乘a,然后,b就变成偶数啦。
代码如下:(别忘了取模)
#include<iostream>
#define int long long
using namespace std;
signed main(){
int a,b,p;
cin>>a>>b>>p;
int x=a,y=b,m=p;
int ans=1;
while(b>0){
if(b%2==0){//如果b为偶数
b=b/2;//除以2
a=a*a%p;//乘方
}
else{//为奇数
b=b-1;//让它变成偶数
ans=ans*a%p;//先乘一次
b/=2;
a=a*a%p;//再次乘方
}
}
printf("%lld^%lld mod %lld=%lld\n",x,y,m,ans);
return 0;
}