Problem 1752 A^B mod C
Accept: 579 Submit: 2598
Time Limit: 1000 mSec Memory Limit : 32768 KB
Problem Description
Given A,B,C, You should quickly calculate the result of A^B mod C. (1<=A,B,C<2^63).
Input
There are multiply testcases. Each testcase, there is one line contains three integers A, B and C, separated by a single space.
Output
For each testcase, output an integer, denotes the result of A^B mod C.
Sample Input
3 2 4 2 10 1000
Sample Output
1 24
Source
FZU 2009 Summer Training IV--Number Theory 很多题目,平时提交是对的。但是比赛的时候,数据加强,数字范围变化就错了。
溢出......
这个题,两个知识点,很好的题目。
1. a^b%m;
2. a*b%m;
由于这道题,数字的大小是(1<=A,B,C<2^63).
一开始,我们都会想到用__int64 或者 long long
计算的方法也有多种,但是本质上是一样的。
整数的二进制拆分。
在计算的过程中会出现一些问题。
错误的代码:
1 Source Code 2 RunID: 508246UserID: 987690183Submit time: 2013-08-12 18:14:52Language: Visual C++Length: 497 Bytes.Result: Wrong Answer 3 4 #include<iostream> 5 #include<cstdio> 6 #include<cstdlib> 7 #include<cstring> 8 using namespace std; 9 10 11 12 unsigned __int64 mgml(unsigned __int64 a,unsigned __int64 n,unsigned __int64 m ) 13 { 14 unsigned __int64 ans=1; 15 a=a%m; 16 while(n) 17 { 18 if(n&1) 19 { 20 ans=(ans*a)%m;//当数字很大的时候,ans*a就溢出了。 21 } 22 n=n>>1; 23 a=(a*a)%m;//这边的也是一样的。 24 } 25 return ans; 26 } 27 28 int main() 29 { 30 unsigned __int64 a,b,c; 31 while(scanf("%I64u%I64u%I64u",&a,&b,&c)>0) 32 { 33 printf("%I64u ",mgml(a,b,c)); 34 } 35 return 0; 36 }
因此,通过以前的方法就难以解决这个问题,这也是这道题好的地方了。
处理的方法,加一个a*b%m的函数,解决在错误代码里遇到的问题。
AC代码:
1 #include<iostream> 2 #include<stdio.h> 3 #include<cstring> 4 #include<cstdlib> 5 using namespace std; 6 7 typedef __int64 LL; 8 9 LL pow1_sum(LL a,LL b,LL mod) 10 { 11 a=a%mod; 12 b=b%mod; 13 LL cur=0; 14 while(b) 15 { 16 if(b&1) 17 { 18 cur=cur+a; 19 if(cur>=mod) cur=cur-mod; 20 } 21 a=a<<1; 22 if(a>=mod) a=a-mod; 23 b=b>>1; 24 } 25 return cur; 26 } 27 LL pow_sum(LL a,LL b,LL mod) //a^b%mod 28 { 29 LL cur= 1; 30 a=a%mod; 31 while(b) 32 { 33 if(b&1) 34 { 35 cur=pow1_sum(cur,a,mod); 36 } 37 a=pow1_sum(a,a,mod); 38 b=b>>1; 39 } 40 return cur; 41 } 42 void solve(LL a,LL b,LL mod) 43 { 44 LL result = pow_sum(a,b,mod); 45 printf("%I64d ",result); 46 } 47 int main() 48 { 49 LL a,b,mod; 50 while(scanf("%I64d%I64d%I64d",&a,&b,&mod)>0) 51 { 52 solve(a,b,mod); 53 } 54 return 0; 55 }
这道题,没有很复杂的算法,但是又容易出错,很值得推荐