前置知识
在之前的学习中,我们了解了二进制与位运算的操作。
取模运算是算法中的基础操作。为了避免溢出且减少冲突,通常使用一个足够大且为质数的数字进行取模,例如 10^9 + 7。
关于取模有一个重要公式:
(x * y) % z ==> ((x % z) * (y % z)) % z
证明:
假设 x = a * z + b, y = c * z + d,则:
(x * y) % z
= ((a*z + b) * (c*z + d)) % z
= (a*c*z*z + a*z*d + b*c*z + b*d) % z
= 0 + 0 + 0 + (b*d) % z
b、d 为 x、y 本身的取模结果。
知道这个公式,当两个较大的数做乘法时,我们先求余再相乘,可以有效避免溢出。
快速幂算法
快速幂(Exponentiation by squaring)是一种简单而有效的算法,它可以 O(log n) 的时间复杂度计算乘方。
日常生活中,计算 3^10 可以通过内置函数或循环实现。若通过循环实现 x^y,时间复杂度为 O(n)。
对于大指数(如百万次方),需要优化。利用分治思想,将 x^y 转化为 (x*x)^(y/2),时间复杂度降为 O(log n)。
若 y 不能被 2 整除,例如计算 3^10:
3^10 = (3*3)^5 = 9^5
9^5 = (9^4)*(9^1)
递归实现
def quick_pow(x, y):
if y == 0:
return 1
ret = quick_pow(x, y // )
ret * ret y % == ret * ret * x

