为何叫快速幂呢?显然是幂运算的快速方法。
我们计算A^n的朴素的方法就是循环n次来求幂咯,这样便得到O(n)时间复杂度的方法,其实大家都想得到一种优化的方法即A^n=A^(n/2)*A^(n/2),一直递归下去,其间就可以省略很多不必要的计算,得到O(logn)的方法。
下面就介绍一种用二进制方法求快速幂的运算。
我们用二进制来代替幂n,比如10的二进制为1010(二进制相信大家都会)
这里第1位和第3位(倒着从0开始数的)为1,于是我们求A^10便转化为A^10=A^(2^3)*A^(2^1);这样做有什么好处呢?
我们知道对于10(1010)来说每一个二进制位都对应着A的几次幂呢?分别是A^1 A^2 A^4 A^8(也是从低位开始的);注意到这里前后的幂的关系:A^(n) = A^(n-1)*A^(n-1)(这里的n表示二进制位的位数)不是么?比如A^8=A^4*A^4, A^4=A^2*A^2....
于是我们求A^n次方就可以写下如下的代码
while(n)
{
if(n&1) //表示最后一位是1,因为我们可以通过移位来判断n的二进制位中哪些位为1
{
ans *= A;//ans表示最后的结果
}
A = A*A; //注意上面讲的前后二进制位对应的A的几次方的关系(移位的同时顺便计算出那一位代表的是A的几次方)
n>>1;
}
往往我们计算的不是求某个数的快速幂,二是求矩阵的快速幂,
当然他们是一样的。
注意到上面算法的时间复杂度仅仅取决于幂的二进制位中最高位在哪个位,即便幂可能达到2^31次方 我们也只需要31次循环便做完了。怎么样,效率很好吧?
推荐一个快速幂的如门题目
http://poj.org/problem?id=3070
通过这道题目我们可以练习一下快速幂也可以了解到斐波那契数列与矩阵的密切关系(数学真的好神奇的说)