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

时间:2020-12-20 16:40:03

Problem 1752 A^B mod C

Accept: 579    Submit: 2598
Time Limit: 1000 mSec    Memory Limit : 32768 KB

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

Given A,B,C, You should quickly calculate the result of A^B mod C. (1<=A,B,C<2^63).

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

There are multiply testcases. Each testcase, there is one line contains three integers A, B and C, separated by a single space.

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

For each testcase, output an integer, denotes the result of A^B mod C.

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

3 2 4 2 10 1000

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

1 24

福州大学oj 1752  A^B mod C  ===>数论的基本功。位运用。五星***** 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
计算的方法也有多种,但是本质上是一样的。
整数的二进制拆分。
在计算的过程中会出现一些问题。
错误的代码:
 
  Source Code
RunID: 508246UserID: 987690183Submit time: -- ::52Language: Visual C++Length: Bytes.Result: Wrong Answer #include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
using namespace std; unsigned __int64 mgml(unsigned __int64 a,unsigned __int64 n,unsigned __int64 m )
{
unsigned __int64 ans=;
a=a%m;
while(n)
{
if(n&)
{
ans=(ans*a)%m;//当数字很大的时候,ans*a就溢出了。
}
n=n>>;
a=(a*a)%m;//这边的也是一样的。
}
return ans;
} int main()
{
unsigned __int64 a,b,c;
while(scanf("%I64u%I64u%I64u",&a,&b,&c)>)
{
printf("%I64u\n",mgml(a,b,c));
}
return ;
}

因此,通过以前的方法就难以解决这个问题,这也是这道题好的地方了。

处理的方法,加一个a*b%m的函数,解决在错误代码里遇到的问题。

AC代码:

 #include<iostream>
#include<stdio.h>
#include<cstring>
#include<cstdlib>
using namespace std; typedef __int64 LL; LL pow1_sum(LL a,LL b,LL mod)
{
a=a%mod;
b=b%mod;
LL cur=;
while(b)
{
if(b&)
{
cur=cur+a;
if(cur>=mod) cur=cur-mod;
}
a=a<<;
if(a>=mod) a=a-mod;
b=b>>;
}
return cur;
}
LL pow_sum(LL a,LL b,LL mod) //a^b%mod
{
LL cur= ;
a=a%mod;
while(b)
{
if(b&)
{
cur=pow1_sum(cur,a,mod);
}
a=pow1_sum(a,a,mod);
b=b>>;
}
return cur;
}
void solve(LL a,LL b,LL mod)
{
LL result = pow_sum(a,b,mod);
printf("%I64d\n",result);
}
int main()
{
LL a,b,mod;
while(scanf("%I64d%I64d%I64d",&a,&b,&mod)>)
{
solve(a,b,mod);
}
return ;
}

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