Related Articles

Related Articles

Sum of all perfect square divisors of numbers from 1 to N
  • Last Updated : 15 Oct, 2020

Given a number N, the task is to find the sum of all the perfect square divisors of numbers from 1 to N
Examples: 

Input: N = 5 
Output:
Explanation: N = 5 
Perfect square divisors of 1 = 1. 
Similarly, perfect square divisors of 2, 3 = 1. 
Perfect square divisors of 4 = 1, 4. 
Perfect square divisors of 5 = 1 (of course for any prime only 1 will be the perfect square divisor) 
So, total sum = 1+1+1+(1+4)+1 = 9.

Input: N = 30 
Output: 126

Input: N = 100 
Output: 910 

Naive Approach: This approach is based on the approach implemented in this article 
The above problem can be solved in O(N1/k) for any Kth power divisors, where N is the number up to which we have to find the sum. This is because, in this sum, every number will contribute floor(N/p) or int(N/p) times. Thus, while iterating through these perfect powers, we just need to add [p * int(N/p)] to the sum. 



Time Complexity: O(√N)

Efficient Approach: 

  • Let us start from start = 2, find the largest range (start to end) for which floor(N/(start2)) = floor(N/(end2))
  • The contribution of all perfect squares in the interval [start, end] will contribute floor(N/(start2)) times, hence we can do update for this range at once.
  • Contribution for range [start, end] can be given as:

floor(N/(start2))*(sumUpto(end) – sumUpto(start-1))

  • How to find range? 
    For a given value of start, end can be found by

sqrt(N/K), where K = floor(N/(start^2))

  • Now the next range can be found by substituting start = end+1.

Time complexity: O(N1/3) as N/(x2) cannot take more than N1/3 different values for a fixed value of N.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ Program to find the
// sum of all perfect square
// divisors of numbers from 1 to N
 
#include <bits/stdc++.h>
using namespace std;
 
#define MOD 1000000007
#define int unsigned long long
 
// Function for finding inverse
// of a number iteratively
// Here we will find the inverse
// of 6, since it appears as
// denominator in the formula of
// sum of squares from 1 to N
int inv(int a)
{
    int o = 1;
    for (int p = MOD - 2;
         p > 0; p >>= 1) {
 
        if ((p & 1) == 1)
            o = (o * a) % MOD;
        a = (a * a) % MOD;
    }
    return o;
}
 
// Store the value of the inverse
// of 6 once as we don't need to call
// the function again and again
int inv6 = inv(6);
 
// Formula for finding the sum
// of first n squares
int sumOfSquares(int n)
{
 
    n %= MOD;
    return (((n * (n + 1))
             % MOD * (2 * n + 1))
            % MOD * inv6)
           % MOD;
}
 
int sums(int n)
{
 
    // No perfect square
    // exists which is
    // less than 4
    if (n < 4)
        return 0;
 
    // Starting from 2, present value
    // of start is denoted here as
    // curStart
    int curStart = 2, ans = 0;
 
    int sqrtN = sqrt(n);
    while (curStart <= n / curStart) {
 
        int V = n / (curStart * curStart);
 
        // Finding end of the segment
        // for which the contribution
        // will be same
        int end = sqrt(n / V);
 
        // Using the above mentioned
        // formula to find ans % MOD
        ans += (n / (curStart * curStart)
                % MOD * (sumOfSquares(end)
                         + MOD
                         - sumOfSquares(curStart - 1)))
               % MOD;
 
        if (ans >= MOD)
            ans -= MOD;
 
        // Now for mthe next iteration
        // start will become end+1
        curStart = end + 1;
    }
 
    // Finally returning the answer
    return ans;
}
 
// Driver Code
int32_t main()
{
    int input[] = { 5 };
    for (auto x : input) {
        cout << "sum of all perfect"
             << " square divisors from"
             << " 1 to " << x
             << " is: ";
 
        // Here we are adding x
        // because we have not
        // counted 1 as perfect
        // squares so if u want to
        // add it you can just add
        // that number to the ans
        cout << x + sums(x) << endl;
    }
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to find the
// sum of all perfect square
// divisors of numbers from 1 to N
import java.util.*;
 
class GFG{
 
static final int MOD = 7;
 
// Function for finding inverse
// of a number iteratively
// Here we will find the inverse
// of 6, since it appears as
// denominator in the formula of
// sum of squares from 1 to N
static int inv(int a)
{
    int o = 1;
    for(int p = MOD - 2;
            p > 0; p >>= 1)
    {
        if ((p & 1) == 1)
            o = (o * a) % MOD;
             
        a = (a * a) % MOD;
    }
    return o;
}
 
// Store the value of the inverse
// of 6 once as we don't need to call
// the function again and again
static int inv6 = inv(6);
 
// Formula for finding the sum
// of first n squares
static int sumOfSquares(int n)
{
    n %= MOD;
    return (((n * (n + 1)) %
            MOD * (2 * n + 1)) %
            MOD * inv6) % MOD;
}
 
static int sums(int n)
{
     
    // No perfect square
    // exists which is
    // less than 4
    if (n < 4)
        return 0;
 
    // Starting from 2, present value
    // of start is denoted here as
    // curStart
    int curStart = 2, ans = 0;
 
    int sqrtN = (int)Math.sqrt(n);
    while (curStart <= n / curStart)
    {
        int V = n / (curStart * curStart);
 
        // Finding end of the segment
        // for which the contribution
        // will be same
        int end = (int)Math.sqrt(n / V);
 
        // Using the above mentioned
        // formula to find ans % MOD
        ans += (n / (curStart * curStart) %
              MOD * (sumOfSquares(end) + MOD -
                     sumOfSquares(curStart - 1))) % MOD;
 
        if (ans >= MOD)
            ans -= MOD;
 
        // Now for mthe next iteration
        // start will become end+1
        curStart = end + 1;
    }
 
    // Finally returning the answer
    return ans;
}
 
// Driver Code
public static void main(String[] args)
{
    int input[] = {5};
    for(int x : input)
    {
        System.out.print("sum of all perfect " +
                         "square divisors from " +
                         "1 to " +  x + " is: ");
 
        // Here we are adding x
        // because we have not
        // counted 1 as perfect
        // squares so if u want to
        // add it you can just add
        // that number to the ans
        System.out.print(x + sums(x) + "\n");
    }
}
}
 
// This code is contributed by Amit Katiyar

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program to find the
# sum of all perfect square
# divisors of numbers from 1 to N
from math import *
MOD = 1000000007
 
# Function for finding inverse
# of a number iteratively
# Here we will find the inverse
# of 6, since it appears as
# denominator in the formula of
# sum of squares from 1 to N
def inv (a):
 
    o = 1
    p = MOD - 2
    while (p > 0):
 
        if (p % 2 == 1):
            o = (o * a) % MOD
 
        a = (a * a) % MOD
        p >>= 1
 
    return o
 
# Store the value of the inverse
# of 6 once as we don't need to call
# the function again and again
inv6 = inv(6)
 
# Formula for finding the sum
# of first n squares
def sumOfSquares (n):
 
    n %= MOD
    return (((n * (n + 1)) %
            MOD * (2 * n + 1)) %
            MOD * inv6) % MOD
 
def sums (n):
 
    # No perfect square exists which
    # is less than 4
    if (n < 4):
        return 0
 
    # Starting from 2, present value
    # of start is denoted here as curStart
    curStart = 2
    ans = 0
 
    sqrtN = int(sqrt(n))
    while (curStart <= n // curStart):
        V = n // (curStart * curStart)
 
        # Finding end of the segment for
        # which the contribution will be same
        end = int(sqrt(n // V))
 
        # Using the above mentioned
        # formula to find ans % MOD
        ans += ((n // (curStart * curStart) %
                MOD * (sumOfSquares(end) +
                MOD - sumOfSquares(curStart - 1))) % MOD)
 
        if (ans >= MOD):
            ans -= MOD
 
        # Now for mthe next iteration
        # start will become end+1
        curStart = end + 1
 
    # Finally return the answer
    return ans
 
# Driver Code
if __name__ == '__main__':
 
    Input = [5]
    for x in Input:
        print("sum of all perfect "\
              "square " , end = '')
        print("divisors from 1 to", x,
              "is: ", end = '')
 
        # Here we are adding x because we have
        # not counted 1 as perfect squares so if u
        # want to add it you can just add that
        # number to the ans
        print(x + sums(x))
 
# This code is contributed by himanshu77

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program to find the
// sum of all perfect square
// divisors of numbers from 1 to N
using System;
class GFG{
 
static readonly int MOD = 7;
 
// Function for finding inverse
// of a number iteratively
// Here we will find the inverse
// of 6, since it appears as
// denominator in the formula of
// sum of squares from 1 to N
static int inv(int a)
{
  int o = 1;
  for(int p = MOD - 2;
          p > 0; p >>= 1)
  {
    if ((p & 1) == 1)
      o = (o * a) % MOD;
 
    a = (a * a) % MOD;
  }
   
  return o;
}
 
// Store the value of the inverse
// of 6 once as we don't need to call
// the function again and again
static int inv6 = inv(6);
 
// Formula for finding the sum
// of first n squares
static int sumOfSquares(int n)
{
  n %= MOD;
  return (((n * (n + 1)) %
            MOD * (2 * n + 1)) %
            MOD * inv6) % MOD;
}
 
static int sums(int n)
{
  // No perfect square
  // exists which is
  // less than 4
  if (n < 4)
    return 0;
 
  // Starting from 2, present
  // value of start is denoted
  // here as curStart
  int curStart = 2, ans = 0;
 
  int sqrtN = (int)Math.Sqrt(n);
  while (curStart <= n / curStart)
  {
    int V = n / (curStart * curStart);
 
    // Finding end of the segment
    // for which the contribution
    // will be same
    int end = (int)Math.Sqrt(n / V);
 
    // Using the above mentioned
    // formula to find ans % MOD
    ans += (n / (curStart * curStart) %
            MOD * (sumOfSquares(end) + MOD -
                   sumOfSquares(curStart -
                                1))) % MOD;
 
    if (ans >= MOD)
      ans -= MOD;
 
    // Now for mthe next iteration
    // start will become end+1
    curStart = end + 1;
  }
 
  // Finally returning
  // the answer
  return ans;
}
 
// Driver Code
public static void Main(String[] args)
{
  int []input = {5};
  foreach(int x in input)
  {
    Console.Write("sum of all perfect " +
                  "square divisors from " +
                  "1 to " + x + " is: ");
 
    // Here we are adding x
    // because we have not
    // counted 1 as perfect
    // squares so if u want to
    // add it you can just add
    // that number to the ans
    Console.Write(x + sums(x) + "\n");
  }
}
}
 
// This code is contributed by Rajput-Ji

chevron_right


Output: 

sum of all perfect square divisors from 1 to 5 is: 9




 

Time Complexity: O(N1/3
 

competitive-programming-img




My Personal Notes arrow_drop_up
Recommended Articles
Page :