题目描述
给你三个整数 a , b , p a,b,p a,b,p,求 a b m o d p a^b \bmod p abmodp。
输入格式
输入只有一行三个整数,分别代表 a , b , p a,b,p a,b,p。
输出格式
输出一行一个字符串 a^b mod p=s
,其中
a
,
b
,
p
a,b,p
a,b,p 分别为题目给定的值,
s
s
s 为运算结果。
样例 #1
样例输入 #1
2 10 9
样例输出 #1
2^10 mod 9=7
提示
样例解释
2 10 = 1024 2^{10} = 1024 210=1024, 1024 m o d 9 = 7 1024 \bmod 9 = 7 1024mod9=7。
数据规模与约定
对于 100 % 100\% 100% 的数据,保证 0 ≤ a , b < 2 31 0\le a,b < 2^{31} 0≤a,b<231, a + b > 0 a+b>0 a+b>0, 2 ≤ p < 2 31 2 \leq p \lt 2^{31} 2≤p<231。
前置知识
在八年级上学期的数学课本中,有这样一个公式
a
n
×
a
m
=
a
m
+
n
a^n \times a^m =a^{m+n}
an×am=am+n .
注:此处的
a
a
a 与题目中的
a
a
a 无关;
公式推导
根据前置知识中的公式,可以发现:
a
b
=
a
b
2
+
b
2
=
a
b
2
×
a
b
2
\begin {aligned} a^b &= a^{ \frac{b}{2}+\frac{b}{2}} &=a^{\frac{b}{2}}\times a^{\frac{b}{2}} \end{aligned}
ab=a2b+2b=a2b×a2b
由于C++的除法是取余的,所以代码使用的公式应该是下面这个公式,并且要考虑的
b
=
1
或
b
=
0
b=1\text{ 或 }b=0
b=1 或 b=0 时的特殊情况。
a
b
=
{
a
b
2
×
a
b
2
b
是偶数
a
⌊
b
2
⌋
×
a
⌊
b
2
⌋
×
a
b
是奇数
a
b
=
1
1
b
=
0
a^b=\begin{cases}a^{\frac{b}{2}}\times a^{\frac{b}{2}}&\text{$b$是偶数}\\a^{\lfloor\frac{b}{2}\rfloor}\times a^{\lfloor\frac{b}{2}\rfloor}\times a&\text{$b$是奇数}\\a&b=1\\1&b=0\end{cases}
ab=⎩
⎨
⎧a2b×a2ba⌊2b⌋×a⌊2b⌋×aa1b是偶数b是奇数b=1b=0
代码实现
通过上面的公式,就可以写出对应的代码。注意要取余,“能多模不少模”。
另外,这道题要开long long
#include<iostream>
#include<cmath>
#include<iomanip>
#include<queue>
#include<map>
#include<string>
using namespace std;
long long Mi(long long a,long long b,long long mod)
{
if(b==0) return 1;
if(b==1) return a%mod;
if(b%2==1) return a%mod*Mi(a,b/2,mod)%mod*Mi(a,b/2,mod)%mod;//当b为奇数时
else return Mi(a,b/2,mod)%mod*Mi(a,b/2,mod)%mod;//当b为偶数时
}
别急,这个代码仍有一些问题,可能会爆TLE,为什么?
因为当
b
≠
0
且
b
≠
1
b\ne0\text{ 且 }b\ne1
b=0 且 b=1时程序会调用两次函数,那么为了避免重复调用,我们不放用一个变量
n
u
m
num
num 存储
a
⌊
b
2
⌋
a^{\lfloor \frac{b}{2}\rfloor}
a⌊2b⌋ 的值,代码如下
long long Mi(long long a,unsigned long long b,long long mod)
{
if(b==0) return 1;
if(b==1) return a%mod;
long long num;
num=Mi(a,b>>1,mod);
if(b%2==0) return num%mod*num%mod;
else return a%mod*num%mod*num%mod;
}
AC代码
注意输出格式!
#include<iostream>
using namespace std;
long long Mi(long long a,unsigned long long b,long long mod)
{
if(b==0) return 1;
if(b==1) return a%mod;
long long num;
num=Mi(a,b>>1,mod);
if(b%2==0) return num%mod*num%mod;
else return a%mod*num%mod*num%mod;
}
int main()
{
long long a,b,mod;
cin>>a>>b>>mod;
cout<<a<<"^"<<b<<" mod "<<mod<<"="<<Mi(a,b,mod)<<endl;
return 0;
}