快速幂总结

原理

快速幂是对以下形式的式子进行计算

A n A^n An

其中,A可以是整数、浮点数、矩阵等。n只能是整数,因为这是能够让这个计算变快的原因。

传统的幂次计算需要进行n-1次乘法,时间复杂度为O(n), 如下
A n =     A × A × . . × A ⏟ n 个 \begin{matrix} A^n = \\ \ \end{matrix} \ \begin{matrix} \underbrace{ A\times A \times ..\times A } \\ n 个 \end{matrix} An=   A×A×..×An

但是快速幂算法,把计算过程拆分成如下形式。假设n是一个32位整数无符号数, n i ∈ { 0 , 1 } n_i\in \{0, 1\} ni{0,1}表示n的二进制表示中从右往左数第i位。i从0开始。
n = n 0 2 0 + n 1 2 1 + . . . + n 31 2 31 n=n_02^0+n_12^1 + ... + n_{31}2^{31} n=n020+n121+...+n31231

A n = A n 0 2 0 + n 1 2 1 + . . . + n 31 2 31 = A n 0 2 0 × A n 1 2 1 × . . × A n 31 2 31 \begin{split} A^n &= A^{n_02^0+n_12^1 + ... + n_{31}2^{31}} \\ &= A^{n_02^0} \times A^{n_12^1} \times ..\times A^{n_{31}2^{31}} \end{split} An=An020+n121+...+n31231=An020×An121×..×An31231
由此可见,分解后一共有32项相乘。如果每一项都能在O(1)时间内解决,则总的乘法计算次数不会超过31次。实际的次数会小于31,取决于n中比特1的个数,因为如果 n i = 0 n_i = 0 ni=0, 那么该项不需要被乘,直接跳过这一项的计算。

对于 n n n来说,比特1的个数不会超过 l o g 2 n log_2n log2n。因此总的时间复杂度为 O ( l o g 2 n ) O(log_2n) O(log2n)

知道了计算量是如何减小的,现在关键是怎么在O(1)的时间内计算其中每一项。可以利用递推的思想。如下:
A 2 0 = A 1 = A A 2 1 = A 2 = A 1 × A 1 A 2 1 = A 4 = A 2 × A 2 A 2 3 = A 8 = A 4 × A 4 . . . A 2 31 = A 2147483648 = A 2 30 × A 2 30 \begin{split} A^{2^0} &= A^1 = A \\ A^{2^1} &= A^2 = A^1\times A^1 \\ A^{2^1} &= A^4 = A^2\times A^2 \\ A^{2^3} &= A^8 = A^4\times A^4 \\ ...& \\ A^{2^{31}} &= A^{2147483648} = A^{2^{30}}\times A^{2^{30}} \\ \end{split} A20A21A21A23...A231=A1=A=A2=A1×A1=A4=A2×A2=A8=A4×A4=A2147483648=A230×A230

代码

代码如下:

int pow(int a,int n){
    int ans = 1;
	while(n > 0){
	   if((n & 1) == 1){
           ans *= a;
       }
       a *= a;
       n >>= 1;
	}
	return ans;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值