给定正整数N ,任务是找到从1到N的所有数字的除数之和。
例子:
Input: N = 5
Output: 21
Explanation:
Sum of divisors of all numbers from 1 to 5 = 21.
Divisors of 1 -> 1
Divisors of 2 -> 1, 2
Divisors of 3 -> 1, 3
Divisors of 4 -> 1, 2, 4
Divisors of 5 -> 1, 5, hence Sum = 21
Input: N = 6
Output: 33
Explanation:
Sum of divisors of all numbers from 1 to 6 = 33.
Divisors of 1 -> 1
Divisors of 2 -> 1, 2
Divisors of 3 -> 1, 3
Divisors of 4 -> 1, 2, 4
Divisors of 5 -> 1, 5
Divisors of 6 -> 1, 2, 3, 6, hence sum = 33
朴素和线性方法:有关朴素和线性方法,请参阅从1到n的所有除数之和。
对数方法:指从1到N的所有除数的和。设置2为对数时间法。
高效方法:
请按照以下步骤解决问题:
- 我们可以观察到,从1数每x到N,发生在总结它的最高倍数是≤ñ。
- 因此,通过公式x * floor(N / x)计算每个x的贡献,
- 可以看出,对于一系列连续数l 1 ,l 2 ,l 3 ….l r , floor(N / i)相同。因此,代替为每个i计算l i * floor(N / i) ,而是计算(l 1 + l 2 + l 3 +…。+ l r )* floor(N / l 1 ) ,从而降低了计算复杂度。
下面是上述方法的实现:
C++
// C++ Program to implement
// the above approach
#include
using namespace std;
#define int long long int
#define m 1000000007
// Function to find the sum
// of all divisors of all
// numbers from 1 to N
void solve(long long n)
{
// Stores the sum
long long s = 0;
for (int l = 1; l <= n;) {
// Marks the last point of
// occurence with same count
int r = n / floor(n / l);
int x = (((r % m) * ((r + 1)
% m))
/ 2)
% m;
int y = (((l % m) * ((l - 1)
% m))
/ 2)
% m;
int p = ((n / l) % m);
// Calculate the sum
s = (s + (((x - y) % m) * p) % m
+ m)
% m;
s %= m;
l = r + 1;
}
// Return the result
cout << (s + m) % m;
}
// Driver Code
signed main()
{
long long n = 12;
solve(n);
return 0;
}
Java
// Java Program to implement
// the above approach
import java.util.*;
class GFG{
static final int m = 1000000007;
// Function to find the sum
// of all divisors of all
// numbers from 1 to N
static void solve(long n)
{
// Stores the sum
long s = 0;
for (int l = 1; l <= n;)
{
// Marks the last point of
// occurence with same count
int r = (int)(n /
Math.floor(n / l));
int x = (((r % m) *
((r + 1) %
m)) / 2) % m;
int y = (((l % m) *
((l - 1) %
m)) / 2) % m;
int p = (int)((n / l) % m);
// Calculate the sum
s = (s + (((x - y) %
m) * p) %
m + m) % m;
s %= m;
l = r + 1;
}
// Return the result
System.out.print((s + m) % m);
}
// Driver Code
public static void main(String[] args)
{
long n = 12;
solve(n);
}
}
// This code is contributed by Rajput-Ji
Python3
# Python3 Program to implement
# the above approach
import math
m = 1000000007
# Function to find the sum
# of all divisors of all
# numbers from 1 to N
def solve(n):
# Stores the sum
s = 0;
l = 1;
while(l < n + 1):
# Marks the last poof
# occurence with same count
r = (int)(n /
math.floor(n / l));
x = ((((r % m) *
((r + 1) % m)) / 2) % m);
y = ((((l % m) *
((l - 1) % m)) / 2) % m);
p = (int)((n / l) % m);
# Calculate the sum
s = ((s + (((x - y) % m) *
p) % m + m) % m);
s %= m;
l = r + 1;
# Return the result
print (int((s + m) % m));
# Driver Code
if __name__ == '__main__':
n = 12;
solve(n);
# This code is contributed by Rajput-Ji
C#
// C# program to implement
// the above approach
using System;
class GFG{
static readonly int m = 1000000007;
// Function to find the sum
// of all divisors of all
// numbers from 1 to N
static void solve(long n)
{
// Stores the sum
long s = 0;
for(int l = 1; l <= n;)
{
// Marks the last point of
// occurence with same count
int r = (int)(n /(Math.Floor((double)n/l)));
int x = (((r % m) *
((r + 1) %
m)) / 2) % m;
int y = (((l % m) *
((l - 1) %
m)) / 2) % m;
int p = (int)((n / l) % m);
// Calculate the sum
s = (s + (((x - y) %
m) * p) %
m + m) % m;
s %= m;
l = r + 1;
}
// Return the result
Console.Write((s + m) % m);
}
// Driver Code
public static void Main(String[] args)
{
long n = 12;
solve(n);
}
}
// This code is contributed by Amit Katiyar
输出
127
时间复杂度: O(√N)
辅助空间: O(1)