快速幂取模算法


起因

刷LeetCode时突然碰到了这种求大指数的问题,这种将理论转化为工程的方式彻底吸引了我,有必要把学习过程记录下来。

目标

计算 $a^b \ mod \ c$ 的值

为什么要在模 $c$ 下计算?

由于指数函数快速增长的性质,$a, b$ 稍微大一点,$a^b$ 就很容易超出编程语言的数据范围,因此往往只能考虑在模 $c$ 下的值,这是一种无奈之举。

快速幂算法

首先假设 $a^b$ 的值不超过数值范围(long),然后考虑计算其值。一种平凡的做法是在循环内依次累乘 $a$,时间复杂度为 $O(b)$;除此之外,还有一种在 $log(b)$ 下的快速幂算法,十分高效。

已知对于任何的正整数 $b\in\mathbb{Z_+}$,都有 $$b=\sum_{i=0}^{\infty} b_i2^i \ (b_i=0\ or\ 1)$$
举个例子,$15=2^3+2^2+2^1+2^0$。

进而,$$a^b=a^{\sum b_i2^i}=\prod a^{b_i2^i}$$
举例,$a^{15}=a^{2^0}a^{2^1}a^{2^2}a^{2^3}=a^{1}a^{2}a^{4}a^{8}$,要注意到$b_i$的取值不同。显然,$a^{8}$可由$a^{4}$直接平方获得。


文章作者: Hiper
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Hiper !
  目录