小朋友,你是否有很多问号:
明明用了快速幂,为啥还是
T
L
E
\color{#4682B4}TLE
TLE ?
题目
快速幂||取余数
简单描述一下:求
b
p
m
o
d
k
b^p\ mod\ k
bp mod k
坑
一般人会利用 ( a ⋅ b ) % c = ( a % c ) ⋅ ( b % c ) % c (a\cdot b)\%\ c\ =(a\%c)\cdot(b\%c)\%c (a⋅b)% c =(a%c)⋅(b%c)%c 这个性质,在循环内部取余,防止结果太大爆掉。但是 Python 自带高精度啊,咱有恃无恐,所以直接调用 fastPow(a, b)%k 来计算结果。然后就妥妥 T L E \color{#4682B4}TLE TLE 了。
为啥呢?因为快速幂
O
(
l
o
g
n
)
O(log\ n)
O(log n) 复杂度的前提是 乘法运算是常数时间。
高精度虽然不会爆掉,但是它的乘法是 大数乘法 ,并不是常数时间。
来做个实验:
import timeit
def pow(a, b):
p = 1
for i in range(b):
p *= a
return p
def fastPow(a, b):
p = 1
while b != 0:
if b & 1:
p *= a
a *= a
b >>= 1
return p
t1 = timeit.default_timer()
a = pow(1, 999999)
t2 = timeit.default_timer()
a = fastPow(3, 999999)
t3 = timeit.default_timer()
print('{:.6f}'.format(t2-t1))
print('{:.6f}'.format(t3-t2))
结果如下:
0.030459
0.186064
“神奇” 的现象出现了:
快速幂比朴素算法还慢好多!
利用内建函数 pow
另外,这题利用 Python 内建函数 pow(b, p, k) 可以直接得到结果。