C++题目详解——快速幂
题目描述 / 题面 / 分析题目
求
A
B
M
O
D
P
A^B MOD \ P
ABMOD P ,其中
P
=
1
E
9
+
7
P = 1E9 + 7
P=1E9+7
注:时间限制为
1
s
1s
1s,数据范围为
a
>
=
b
,
b
>
=
1
0
9
a>= b, b >= 10^9
a>=b,b>=109
拿到这道题,我们会觉得很简单,实际上并不简单
35分思路:
先建立变量一个P=1E9+7
然后计算
A
B
A^B
AB的值,然后使用cmath.h
库里面的%
运算符,计算输出即可!
我们来大概计算一下时间复杂度:
O
(
b
+
?
)
O(b + ?)
O(b+?)
?是计算%的时间复杂度
通过大概得计算,我们可以得知,这种方法肯定会超时
55分思路
可以不用pow函数,自己通过优化方法计算次方
AC满分思路:
额,这个方法涉及到二进制以及位运算,如果没学过位运算的同学可以上网查一查
可以利用二分法来计算快速幂
初始化:定义 ret 变量为 1,用来存储结果。ret 初始化为 1 是因为在乘法过程中,1 是乘法的单位元,不会改变结果。
循环条件:当 b > 0 时,进行循环。b 是指数,每次迭代都会减半。
处理奇数指数:如果 b 是奇数 (b % 2 == 1),则将当前的 a 乘到 ret 上,并对结果取模。具体实现为:
ret = 1LL * ret * a % p;
这里 1LL 用来将 ret 和 a 转换为长整型,避免整数溢出,然后对结果取模。
指数减半:将 a 平方并对结果取模。然后将 b 右移一位,相当于 b 除以 2。具体实现为:
a = 1LL * a * a % p;
b = b / 2;
返回结果:当循环结束时,ret 就是所求的结果 a^b % p。
AC满分代码
#include <bits/stdc++.h>
using namespace std;
const int p = (int)1E9+7;
int fastpow(int a, int b)
{
int ret = 1;
while (b > 0)
{
if (b % 2 == 1)
ret = 1LL * ret * a % p;
a = 1LL * a * a % p;
b = b / 2;
}
return ret;
}
int main()
{
int a, b;
cin >> a >> b;
cout << fastpow(a, b);
return 0;
}