快速幂的作用
当我们做一些高次幂的计算时,就不能直接进行暴力的计算。例如:需要计算 2 n 2^n 2n并且 n ≤ 1 0 18 n\le 10^{18} n≤1018。这时候如果我们直接进行暴力的计算,时间复杂度为 O ( n ) O(n) O(n),那么肯定会超时,这时候我们就需要一些更优美的算法来帮我们解决这个问题。
快速幂的实现
思路
首先我们要明确一点,对于一个
m
n
m^n
mn,当
n
n
n为偶数时,
m
n
=
(
m
2
)
n
2
m^n=(m^2)^\frac n2
mn=(m2)2n。
如果知道了这一点我们的问题就迎刃而解了。
求解
2
k
2^k
2k。
定义:
n
o
w
now
now为当前的底数,
f
f
f为临时存放处。
当
k
k
k为偶数时,
n
o
w
×
=
n
o
w
,
k
/
=
2
now\times=now,k/ =2
now×=now,k/=2
当
k
k
k为奇数时,
k
−
−
,
f
∗
=
n
o
w
k--,f*=now
k−−,f∗=now,然后再以
k
k
k为偶数的情况进行计算。
相信大家看了这简单的算法应该都能理解吧。
Code
int quickpow(int n,int k) {
long long now=n,f=1;
while(k>1) {
if(k%2==1) k--,f*=now;
if(k) now*=now,k/=2;
}
return now*f;
}
例题
Input
Output
这一题我们可以明显的看出规律,答案其实就是
2
n
−
1
2^{n-1}
2n−1。
快速幂求解即可,时间复杂度
O
(
l
o
g
(
n
)
)
O(log(n))
O(log(n))
#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
#define p 1000000007
using namespace std;
long long ans=2,n;
void qpow(long long k) {
long long f=1;
while(k>1) {
if(k%2!=0) f=(ans*f)%p,k--;
if(k) ans=(ans*ans)%p,k/=2;
}
ans=(ans*f)%p;
}
int main() {
scanf("%lld",&n);
qpow(n-1);
printf("%lld",ans);
}