快速幂
什么是快速幂
顾名思义,快速幂就是跑得特别快的算一个数几次方的的运算。
朴素算法
求 an a n 的值
for (int i = 1; i <= n; i++) {
res *= a;
}
显然,复杂度是O( n n )的,这显然不是十分快速的算法。
利用cmath库
res = pow(a, b);
告诉你,实际上它的复杂度也不是很健康,可能不如你的朴素算法快。
快速幂
快速幂的速度到底有都快呢
求的值,只需要O( logn l o g n )的时间。
快速幂是如何实现的呢
求 an a n 的值,我们思考一个问题。
如果
n
n
是一个偶数:
=
a×a×a...×a
a
×
a
×
a
.
.
.
×
a
(
n
n
个) =
a2×a2×...×a2
a
2
×
a
2
×
.
.
.
×
a
2
(
n/2
n
/
2
个
a2
a
2
)
如果
n
n
是一个奇数 :
=
an−1×a
a
n
−
1
×
a
,之后就转化成了偶数的问题。
这样,我们不难发现,每进行一次偶数操作, n n 的值都会变为原来的一半,这样,我们就可以在O()的时间内求出 an a n 的值了。
递归代码:(求 an a n )
int Kasumi(int n) {
if (n == 0) {
return 1;
}
int res = Kasumi(n / 2);
res = res * res;
if (n % 2 == 1) {
res *= a;
}
return res;
}
非递归代码:(求 an a n )
int Kasumi(int n) {
int res = 1, base = a;
while (n) {
if (b % 2 == 1) {
ans *= base;
}
base *= base;
b /= 2;
}
return res;
}
如果需要取膜呢?
前提知识储备
a×b a × b % c c = ( % c c ) × × ( b b % ) % c c
然后就没什么了
递归代码:(求 % mod m o d )
int Kasumi(int n) {
if (n == 0) {
return 1;
}
int res = Kasumi(n / 2);
res = res * res % mod;
if (n % 2 == 1) {
res = (res * a) % mod;
}
return res;
}
非递归代码:(求 an a n % mod m o d )
int Kasumi(int n) {
int res = 1, base = a;
while (n) {
if (b % 2 == 1) {
ans = (ans * base) % mod;
}
base = (base * base) % mod;
b /= 2;
}
return res;
}