黑客等级项目的数学解决方案:48

时间:2014-09-20 20:36:29

标签: math series

问题来自Hacker Rank,我想要数学解决方案......

查找该系列的最后十位数字......

1^1 + 2^2 + 3^3 + ⋯ + N^N

如果N太大了

as where 1 <= N <= 2000000

我的代码循环遍历N,但是为N> 1000000完成需要花费太多时间。

任何减少时间的想法???

code:
n = int(input())
if(n>=1 and n<=2*1e6):
    s=0
    for i in range(1, n+1):
        s+=(i**i)
    print(s%10000000000)

1 个答案:

答案 0 :(得分:0)

这看起来像Python,所以我假设你正在使用的是什么(你应该使用你正在使用的语言来标记你的问题)。

最大的问题是i**i非常庞大,因此Python使用大整数来跟踪所有内容。由于2e6 ^(2e6)具有12602060个数字,因此计算速度太快(并且超过您需要的10个数字)。这也意味着我将模数移入循环的建议可能没有帮助。

解决方案是在进行取幂时获取模数(有关详细信息,请参阅Modular exponentiation。有些实现are here。使用Python会使这更简单,因为你不要需要担心整数溢出(具有讽刺意味的是,这是导致原始问题的原因)。

但Python使这更容易,因为pow允许您指定可选模数。因此,您可以将原始代码重写为:

n = int(input())
if ( 1<=n<=2e6 ):
  s = 0
  for i in range(1,n+1):
    s += pow(i,i,10**10)
  print(s%(10**10))

但我们可以进一步简化这一点。 Python还包含一个sum函数,因此您可以使用列表推导并将上述内容重写为

n = int(input())
if ( 1<=n<=2e6 ):
  s = sum( pow(i,i,10**10) for i in range(1,n+1) )
  print(s%(10**10))

但仅为一步分配变量是愚蠢的。所以你要把它重写为

n = int(input())
if ( 1<=n<=2e6 ):
  print(sum( pow(i,i,10**10) for i in range(1,n+1) ) % 10**10)

但您可能更喜欢使用Python的命令行界面,而不用担心检查输入:

sum( pow(i,i,10**10) for i in range(1,2*10**6+1) ) % 10**10