我正在尝试编写一个程序来查找前N个自然数之和,即1 + 2 + 3 + .. + N
的模为1000000009
我知道可以通过使用公式N * (N+1) / 2
来完成此操作,但是我正在尝试找到一种递归函数来计算总和。
我尝试搜索网络,但对此没有任何解决办法。
实际上,这里的问题是数字N
最多可以包含100000个数字。
所以,这是我到目前为止尝试过的。
首先,我尝试将数字分成长度为9的各个部分,然后将它们转换为整数,以便可以使用整数运算符执行算术运算。
例如,数字52562372318723712
将被分为52562372
和318723712
。
但是我没有找到一种方法来操纵这些数字。
然后我再次尝试编写如下函数:
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
。
这样可以解决吗?
还是有其他方法可以这样做?
注意:我更喜欢一种类似于上述功能的解决方案,因为我想修改此功能以满足我的其他要求,我想在问问这里之前先尝试一下。但是,如果不可能,任何其他解决方案也将有所帮助。
请给我任何解决的提示。
答案 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