O中第N个自然数的总和(N中的位数)

时间:2019-08-09 13:55:15

标签: python algorithm sum biginteger

我正在尝试编写一个程序来查找前N个自然数之和,即1 + 2 + 3 + .. + N的模为1000000009

我知道可以通过使用公式N * (N+1) / 2来完成此操作,但是我正在尝试找到一种递归函数来计算总和。

我尝试搜索网络,但对此没有任何解决办法。

实际上,这里的问题是数字N最多可以包含100000个数字。

所以,这是我到目前为止尝试过的。

首先,我尝试将数字分成长度为9的各个部分,然后将它们转换为整数,以便可以使用整数运算符执行算术运算。

例如,数字52562372318723712将被分为52562372318723712。 但是我没有找到一种方法来操纵这些数字。

然后我再次尝试编写如下函数:

def find_sum(n):
    # n is a string
    if len(n) == 1:
        # use the formula if single digit
        return int(int(n[0]) * (int(n[0]) + 1) / 2)

    # I'm not sure what to return here
    # I'm expecting some manipulation with n[0] 
    # and a recursive call to the function itself

    # I've also not used modulo here just for testing with smaller numbers
    # I'll add it once I find a solution to this
    return int(n[0]) * something + find_sum(n[1:])

我在这里找不到something。 这样可以解决吗? 还是有其他方法可以这样做?

注意:我更喜欢一种类似于上述功能的解决方案,因为我想修改此功能以满足我的其他要求,我想在问问这里之前先尝试一下。但是,如果不可能,任何其他解决方案也将有所帮助。

请给我任何解决的提示。

1 个答案:

答案 0 :(得分:2)

您最好的选择是只使用N*(N+1)/2公式-而是使用p模版。唯一棘手的部分是用2进行除法-这必须是2 mod p的反函数。对于p素数(或简单地为p奇数),这很容易计算:仅为(p+1)//2

因此:

def find_sum(n,p):
    two_inv = (p+1)//2 #inverse of 2, mod p
    return ((n%p)*((n+1)%p)*two_inv)%p

例如:

>>> find_sum(10000000,1000000009)
4550000
>>> sum(range(1,10000001))%1000000009
4550000

请注意,如果您为p传递了偶数,则上述功能将失败。

在编辑上,正如@ user11908059所观察到的,可以省去乘以2的模逆。作为附加的好处,这种方法不再取决于模数是奇数:

def find_sum2(n,k):
    if n % 2 == 0:
        a,b = (n//2) % k, (n+1) % k
    else:
        a,b = n % k, ((n+1)//2) % k
    return (a*b) % k