一个算法题

195132894
想加个群都那么难

题目

求1<=i<=10**12范围内所有d(i)的和的末12位,d(i)表示i的正约数的和,i为整数

解答

本来写个直接暴力的,可惜太蠢了,运行太久忍不了就给关了
想了想,上网搜下,别人写的我怎么都不懂呢

参考一

def d(n):
    s = 0
    for i in range(1, int(n**0.5)+1):
        s += n//i*i

    i = int(n**0.5)+1
    for j in range(n//i, 0, -1):
        s += j * ((i+n//j)*(n//j-i+1)//2)
        i = n//j+1

    return s
print(d(10**12))

真快,差不多两秒就出答案了。
先是比开平方之后小的数,尤其是1啊2啊3啊这种数,量太大了
直接使用n//i*i的方法,10^12个数必然有10^12/1个1 ,10^12/2个2, 10^12/3个3 ,依此类推
为什么选择最大数的平方根呢,因为平方根正好是n个n嘛

接下来开启懵逼模式

    for j in range(n//i, 0, -1):
        s += j * ((i+n//j)*(n//j-i+1)//2)
        i = n//j+1

j(i+nj)(nji+1)2
大概只剩下我数学学的不好别骗我了。。。。
既然看不懂那就去掉吧

def d(n):
    s = 0
    for i in range(1, int(n*0.5)+1):
        s += n//i*i
    return s
print(d(10**12))

结果这个运算也要运算好久。
这里写图片描述
这张图或许有助于理解
难道说那是高斯的求和公式?先将最大的代进去试试
ni(i+nni)(nnii+1)2
由于都是整除,看起来可能有些奇怪,整除的后果就用大写的来标识吧
ni(i+I)(Ii+1)2
啊,还有整除问题。
(N+NN)(NNN+1)2
感觉不太对,莫非j=1才是最大项的?
(i+n)(ni+1)2
好懂不少了,真是高斯求和。
研究一下为啥这样求吧

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值