AtCoder Context ABC 172 D - Sum of Divisors

本文章为原创文章,未经过允许不得转载
运行要求
运行时间限制: 2sec
内存限制: 1024MB
原题链接

题目
给定一个正整数X,正整数的X的约数的函数为f(X)
给定一个正整数N,求F(1)x1 + F(2)x2 .... + F(N)xN

输入前提条件

  • 1 <=N <= 10000000

输出
输出 F(1)x1 + F(2)x2 .... + F(N)xN


例1
输入

4

输出

23

f(1) = 1
f(2) = 2
f(3) = 2
f(4) = 3
所以最终的结果是
1x1 + 2x2 + 2x3 + 3x4 = 1 + 4 + 6 + 12 = 23

例2
输入

100

输出

26879

例3
输入

10000000

输出

838627288460105

注意溢出问题

读懂题目
从1到N,每个数乘以这个数约数的个数,然后相加
N最大可以达到10的7次方,所以,不能用o(N*N)的复杂度

解题思路
AtCoder Context ABC 172 D - Sum of Divisors_第1张图片
如图所示,我们以N=6为例。
1到6的每个数的约数都在下面的方块中显示
因为最终要求的是
f(1)x1 + f(2)x2 + f(3)x3 + f(4)x4 + f(5)x5 + f(6)x6

我们整体来考虑这个算式的话
蓝色方块下面的彩色小方块,存在的话,就会在最终的结果上贡献蓝色方块的数值
比如红色小方块3,拥有3为约数的蓝色方块是3,6
所以最终结果根据红色方块3的个数和所在地,加上3 和 6

AtCoder Context ABC 172 D - Sum of Divisors_第2张图片
如图所示
拥有1为约数的数都加起来(1 + 2 + 3 + 4 + 5 + 6)

AtCoder Context ABC 172 D - Sum of Divisors_第3张图片
如图所示
拥有2为约数的数都加起来(2 + 4 + 6)

AtCoder Context ABC 172 D - Sum of Divisors_第4张图片
如图所示
拥有3为约数的数都加起来(3 + 6)

AtCoder Context ABC 172 D - Sum of Divisors_第5张图片
如图所示
拥有4为约数的数都加起来(4)
拥有5为约数的数都加起来(5)
拥有6为约数的数都加起来(6)

最后转换成从1到N的等差数列的求和
i为1到N的遍历索引
fn(i) = i + 2i + 3i + 4i ... + ni
n+i <= N
等差数列求和
sum(fn(i)) = ((i + (ni))) n /2

代码

N = int(input())

def calculate(n):
    result = 0
    for i in range(1, n + 1):
        num = n // i
        if num == 1:
            result += i
        else:
            start = i
            end = num * i
            total = ((start + end) * num) // 2
            result += total

    print(result)


calculate(N)

总结

这一题考察了等差数列的应用

※ 另外,我会在我的微信个人订阅号上推出一些文章,欢迎关注
二维码.jpg


你可能感兴趣的:(python3.x)