题目链接:JOE的算数
题目名称:JOE的算数
题目描述:
有一天,JOE终于不能忍受计算a^b%c这种平凡的运算了。所以他决定要求你写一个程序,计算a^b%c。提示:若b为奇数,,a^b=(a^(b/2))^2*a,否则a^b=(a^(b/2))^2。输入格式:
三个非负整数a,b,c;
输出格式:
一个整数ans,表示a^b%c;
样例输入:
7 2 5
样例输出:
4
(100%数据:a <=10^6, b <= 10^9, 1 <= c <= 10^6)
根据提示,逐步对 b 进行除二,若为奇数则多一个a,用 vis记录下来。
需要注意 b 除2的次数越多,a增加的个数应为 2 的次方数增加。
例如:
计算方法确定,写出代码,但是提交会有两组数据超时。发现用来记录的vis最后循环计算多出来的a时,有可能会造成超时。
解决方法:把计算方法写成函数,放进循环里,知道记录的多出来的a少与10000000(10^7以内不会超时)。再循环计算一下多出来的a。最后ac。
代码:
#include<iostream>
#include<math.h>
using namespace std;
typedef long long ll;
ll a,b,c;
ll vis,p;
ll res=1;
void f(ll x){
double k=0.5;
ll sum=0;
ll ans=a;
vis=0;
while(x){
k*=2;
sum++;
if(x%2==1&&x!=1){
vis+=k;
}
x/=2;
}
for(int i=1;i<sum;i++){
ans=((ans%c)*(ans%c))%c;
}
res=((res%c)*(ans%c))%c;
p=vis;
}
int main(){
cin>>a>>b>>c;
// ll q=a;
// for(int i=1;i<b;i++){
// q=((q%c)*(a%c))%c;
// }
// cout<<q<<endl;
if(b==1){
cout<<a%c<<endl;
return 0;
}
if(b==0){
cout<<"1"<<endl;
return 0;
}
f(b);
while(vis>1000000){
f(vis);
}
for(int i=1;i<=p;i++){
res=((res%c)*(a%c))%c;
}
cout<<res%c<<endl;
return 0;
}