📜  从1到N的所有除数之和|套装2

📅  最后修改于: 2021-04-23 07:29:58             🧑  作者: Mango

给定正整数N ,任务是找到前N个自然数的除数之和。

例子:

对于线性时间方法,请参阅从1到N的所有除数之和

方法:
为了优化上述文章中的方法,我们需要寻找具有对数复杂度的解决方案。在最终答案中,数字D被多次添加。让我们尝试观察重复加法的模式。
考虑N = 12

D Number of times added
1 12
2 6
3 4
5, 6 2
7, 8, 9, 10, 11, 12 1

从上面的模式中,观察到每个数字D被添加( N / D )次。另外,有多个具有相同(N / D)的D。因此,我们可以得出结论,对于给定的N和特定的i ,将从( N /( i + 1 ))+ 1到( N / i )的数字相加i次。

现在,假设A =(N /(i + 1)), B =(N / i)
从A到1的数字总和=从1到B的数字总和–从1到A的数字总和
另外,不仅仅是每次将i递增1,而是查找下一个像这样的i,i = N /(N /(i + 1))

下面是上述方法的实现:

C++
// C++ program for
// the above approach
#include
using namespace std;
 
int mod = 1000000007;
  
// Functions returns sum
// of numbers from 1 to n
int linearSum(int n)
{
    return (n * (n + 1) / 2) % mod;
}
  
// Functions returns sum
// of numbers from a+1 to b
int rangeSum(int b, int a)
{
    return (linearSum(b) -
            linearSum(a)) % mod;
}
 
// Function returns total
// sum of divisors
int totalSum(int n)
{
     
    // Stores total sum
    int result = 0;
    int i = 1;
  
    // Finding numbers and
    //its occurence
    while(true)
    {
          
        // Sum of product of each
        // number and its occurence
        result += rangeSum(n / i, n / (i + 1)) *
                          (i % mod) % mod;
          
        result %= mod;
         
        if (i == n)
            break;
             
        i = n / (n / (i + 1));
    }
    return result;
}       
  
// Driver code
int main()
{
    int N = 4;
    cout << totalSum(N) << endl;
  
    N = 12;
    cout << totalSum(N) << endl;
    return 0;
}
 
// This code is contributed by rutvik_56


Java
// Java program for
// the above approach
class GFG{
     
static final int mod = 1000000007;
 
// Functions returns sum
// of numbers from 1 to n
public static int linearSum(int n)
{
    return (n * (n + 1) / 2) % mod;
}
   
// Functions returns sum
// of numbers from a+1 to b
public static int rangeSum(int b, int a)
{
    return (linearSum(b) -
            linearSum(a)) % mod;
}
  
// Function returns total
// sum of divisors
public static int totalSum(int n)
{
      
    // Stores total sum
    int result = 0;
    int i = 1;
   
    // Finding numbers and
    //its occurence
    while(true)
    {
           
        // Sum of product of each
        // number and its occurence
        result += rangeSum(n / i,
                           n / (i + 1)) *
                          (i % mod) % mod;
           
        result %= mod;
          
        if (i == n)
            break;
              
        i = n / (n / (i + 1));
    }
    return result;
}
 
// Driver code
public static void main(String[] args)
{
    int N = 4;
    System.out.println(totalSum(N));
   
    N = 12;
    System.out.println(totalSum(N));
}
}
 
// This code is contributed by divyeshrabadiya07


Python3
# Python3 program for
# the above approach
 
mod = 1000000007
 
# Functions returns sum
# of numbers from 1 to n
def linearSum(n):
    return n*(n + 1)//2 % mod
 
# Functions returns sum
# of numbers from a+1 to b
def rangeSum(b, a):
    return (linearSum(b) - (
          linearSum(a))) % mod
 
# Function returns total
# sum of divisors
def totalSum(n):
 
    # Stores total sum
    result = 0
    i = 1
 
    # Finding numbers and
    # its occurence
    while True:
         
        # Sum of product of each
        # number and its occurence
        result += rangeSum(
            n//i, n//(i + 1)) * (
                  i % mod) % mod;
         
        result %= mod;
        if i == n:
            break
        i = n//(n//(i + 1))
         
    return result       
 
# Driver code
 
N= 4
print(totalSum(N))
 
N= 12
print(totalSum(N))


C#
// C# program for
// the above approach
using System;
 
class GFG{
     
static readonly int mod = 1000000007;
 
// Functions returns sum
// of numbers from 1 to n
public static int linearSum(int n)
{
    return (n * (n + 1) / 2) % mod;
}
   
// Functions returns sum
// of numbers from a+1 to b
public static int rangeSum(int b, int a)
{
    return (linearSum(b) -
            linearSum(a)) % mod;
}
  
// Function returns total
// sum of divisors
public static int totalSum(int n)
{
     
    // Stores total sum
    int result = 0;
    int i = 1;
   
    // Finding numbers and
    //its occurence
    while(true)
    {
           
        // Sum of product of each
        // number and its occurence
        result += rangeSum(n / i,
                           n / (i + 1)) *
                          (i % mod) % mod;
           
        result %= mod;
          
        if (i == n)
            break;
              
        i = n / (n / (i + 1));
    }
    return result;
}
 
// Driver code
public static void Main(String[] args)
{
    int N = 4;
    Console.WriteLine(totalSum(N));
   
    N = 12;
    Console.WriteLine(totalSum(N));
}
}
 
// This code is contributed by Amit Katiyar


输出:
15
127






时间复杂度: O(log N)