快速幂
快速幂是什么
快速幂,顾名思义就是快速地计算出一个幂值,比如求。 如果我们限定在一秒钟内算出,如果我们简单地循环n次,那么n最多为,而且时间复杂度为O(n),也比较慢。
对于5 * 5 * 5 * 5 * 5 * ... * 5,我们可以这样考虑,我们两两分组,化为(5 * 5)* (5 * 5)* ... * (5 * 5)。这样分组以后,我们发现还可以继续分下去(5 * 5 * 5 * 5) * ... * (5 * 5 * 5 * 5),然后还可以继续分下去... 当然,有的时候n并不一定是这种形式,但是所有的正整数都可以写成相加的形式(其实就是转换二进制),例如19 = 16 + 2 + 1。显然时间复杂度为。
下面是一个简单的代码演示:
int res;
while(x != 0){
if(x % 2 == 1){
res = res * a;
}
x = x / 2;
a = a * a;
}
return res;
快速幂作为一种数据处理方式,一般不会单独出题,而是作为题目中的一个中间步骤。 下面我们一起来看一道模板题~
#include <iostream>
#include <cmath>
using namespace std;
long long a, b, p, x, n;
long long ans = 1;
int main(){
cin >> a >> b >> p;
x = b;
n = a;
while(x != 0){
if(x % 2 == 1){
ans = (ans * n) % p;
}
x /= 2;
n = (n * n) % p;
}
ans = ans % p;
printf("%lld^%lld mod %lld=%lld", a, b, p, ans);
return 0;
}
这道题虽然是先让你算出答案后求模p,但是我们如果这样做,会发现会报一堆的WA,这是因为我们在中间的运算过程中,数值范围超出了long long。 那么该怎么办呢?告诉大家一个结论:任意一个数x,有x % p = (x % p) % p。所以我们在每一次循环中,都可以对ans和n进行模p操作,最后的答案也是一样的,而且不会超出范围