写在博客之前:看完了这篇博客,你可能不能完全明白这些算法的原理是什么(博主也不太明白)但是希望,各位看官至少能知道这些东西是什么,怎么用。
先从最简单的快速幂说起。
求幂这个东西想必大家都懂,什么2的3次方,3的六次方,计算的时候,想必大家也能知道该怎么算。一个一个乘嘛,但是这样太费时间了,我们希望获得一个更加快速的方法去求得一个数的幂。
其实,快速幂的思想一直就存在于我们的思考之中。比方说,我要算2的10次幂,我应该怎么算呢?2,4,8,16……nonono,这样太笨了我们会想,把两个2捏成一个4,这样就变成了4的5次幂 然后将两个4捏起来,变成两个16相乘再乘一个4。到这里想必大家都能快速的反映出答案:1024(还记得小学时被老师强迫背20以内的二次方方,三次方么)。相比较一个一个2连续相乘,不知道聪明了多少。计算机也喜欢这样的方式。考虑计算机应该如何快速的计算2的10次幂呢?(暂时忽略位运算)难道计算机也可以像人类一样发现一些便捷计算的规律?答案是肯定的。
首先我们将10换一种写法。 10 = 2^3+2^1. 发现什么了吗?我们可以换一个写法:10 = 1*2^3+0*2^2+1*2^1+0*2^0。是不是有一些像十进制转化成二进制的方法?没错,我们就是要将幂指数写成二进制的形式。从这个二进制数的左侧开始扫描每一位是0还是1.如果是0,则代表0*2^x=0不用进入计算;1时则需要将1*2^x计入答案中。
int q_pow(int a,int n) {
int ans = 1;
while(n) {
if(n&1) {
ans*=a;
}
a*=a;
n >>= 1;
}
return ans;
}
有些人可能会问,既然二进制行,那三进制,四进制,十进制快速幂也应该有啊?
你想啊,计算机是什么进制?二进制。它算什么快?位运算啊。
当然,有的时候算出的幂太大存不下怎么办?一般都要取mod。这里只要取模的过程也很简单,(a*b)%mod==a%mod*b%mod.