我在hackerrank编码并遇到了这个问题: https://www.hackerrank.com/challenges/power-calculation
我的代码适用于小文件和大数字。至于大文件,它会超时。有人可以让它更有效率。
我的代码:
z = []
def modexp(a, n, m):
bits = []
while n:
bits.append(n%2)
n /= 2
solution = 1
bits.reverse()
for x in bits:
solution = (solution*solution)%m
if x:
solution = (solution*a)%m
return solution
for _ in xrange(int(input())):
while True:
try:
x = raw_input()
sum =0
z = x.split(' ')
power = int(z[1])
limit = int(z[0])
for i in range(0,limit+1):
sum = sum%100 + modexp(i%100,power, pow(10,2))
if sum < 10:
print '%02d' % sum
if sum > 10:
print sum%100
except:
break
示例数据 - 输入:
10
487348 808701
204397 738749
814036 784709
713222 692670
890568 452450
686541 933150
935447 202322
559883 847002
468195 111274
833627 238704
示例输出:
76
13
76
75
24
51
20
54
90
42
答案 0 :(得分:0)
通过观察其值mod 100具有100的周期,可以容易地减少功率评估的数量
通过计算K = M*100+L
来分解M=K/100; L=K%100;
。
然后
k=0
至L
权力modexp(k%100,N,100)
发生M+1
次,k=L+1
到99
,它总和发生M
次。 因此,每个功率和可以减少到99次幂计算
通过观察相同数字的增加功率在最后两位数字中是周期性的,可以减少计算功率的努力。通常是序列
1, a % m, a**2 % m, a**3 % m, a**4 % m, ...
在由素数因子的最高多重性给出的某一点之后变为周期性的。一个句点长度由欧拉函数中m
的值给出。
100=2²·5²
的总值为phi(100)=(2-1)·2·(5-1)·5=40
。句点设置之前的偏移量最多为2,对于所有整数a
a**2 % 100 == a**42 % 100 = a**82 % 100 = ...
a**3 % 100 == a**43 % 100 = a**83 % 100 = ...
等等。
这意味着对于N>41
,可以将指数减少到N=2+(N-2) % 40
。 (事实上,人们可以通过40
替换20
。)
作为对运行时间没有太大影响的最后评论,只是代码的复杂性:
实现modexp
的方法较短,此算法也是识别循环不变量的标准练习:
def modexp(a, n, m):
solution = 1
apower = a
while n:
if (n%2): solution = (solution*apower) % m
n /= 2
apower = (apower*apower) % m
return solution