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