使求和功率系列更高效

时间:2016-12-02 11:45:57

标签: python-2.7 math modulus

我在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

1 个答案:

答案 0 :(得分:0)

通过观察其值mod 100具有100的周期,可以容易地减少功率评估的数量 通过计算K = M*100+L来分解M=K/100; L=K%100;

然后

  • k=0L权力modexp(k%100,N,100)发生M+1次,
  • 对于k=L+199,它总和发生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