ADV-275 JOE的算数

题目链接: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 的次方数增加。
例如:

a^7=((a)^2*a2)^2*a1;(a1,a2仅为名字,值都是a,用来区别); vis记录a1时记录个数为1(2^0),记录a2时应为2(2^1);更深层以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;
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值