如何在 Python 中使这段代码更快?

问题描述

input_numbers=list(map(int,input().split()))
sum_number=0

def my_gen(a):
    i=0
    while i <= a:
        yield i
        i += 1

for i in my_gen(input_numbers[0]):
    sum_number += i**input_numbers[1]

print(sum_number%1000000009)

我尝试不使用生成器,但它太慢了。 所以,用发电机再试一次,它也很慢。

我怎样才能让它更快?//

更多信息: 我的得分机器人说超时。 和 (1

&Numpy 不能使用

解决方法

您可以使用 Faulhaber's formula,它只需要对幂值进行循环(而不是从 0 到 N 的十亿个数字)。

from fractions import Fraction
from functools import lru_cache
@lru_cache()
def bernoulli(n,result=True): # optimized version
    A = [Fraction(1,n+1)]
    for j,b in enumerate(bernoulli(n-1,False) if n else []):
        A.append((n-j)*(b-A[-1]))
    return A[-1] if result else A

@lru_cache()
def comb(n,r):
    return 1 if not r else comb(n,r-1)*(n-r+1)//r

def powerSum(N,P):
    result = sum(comb(P+1,j) * bernoulli(j) * N**(P+1-j) for j in range(P+1))
    return (result / (P+1)).numerator

输出:

powerSum(100,3) # 25502500

sum(i**3 for i in range(100+1)) # 25502500 (proof)

powerSum(1000000000,50)%1000000009 
# 265558322 in 0.016 seconds on my laptop

sum(i**50 for i in range(1000000000+1))%1000000009 
# 265558322 (proof in 16.5 minutes)
,

代码很慢,因为您正在计算大数的大指数。但最终输出不需要全和,只需要取模。因此,您可以应用基本的模算术来使计算中的数字更小,同时得到相同的最终答案。

,

这是问题的坏处https://projecteuler.net/problem=429好的部分是自己解决。