福州大学oj 1752 A^B mod C ===>数论的基本功。位运用。五星*****

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\n",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\n",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 }

 


这道题,没有很复杂的算法,但是又容易出错,很值得推荐

posted @ 2013-08-12 19:10  芷水  阅读(529)  评论(0编辑  收藏  举报