问题描述
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 但好的部分是自己解决。