Open In App

Summation of GCD of all the pairs up to n

Last Updated : 13 Feb, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Given a number n, find sum of all GCDs that can be formed by selecting all the pairs from 1 to n.

Examples:

Input : n = 4
Output : 7
Explanation: Numbers from 1 to 4 are: 1, 2, 3, 4
Result = gcd(1,2) + gcd(1,3) + gcd(1,4) + gcd(2,3) + gcd(2,4) + gcd(3,4)
= 1 + 1 + 1 + 1 + 2 + 1
= 7

Input : n = 12
Output : 105

Input : n = 1
Output : 0

Input : n = 2
Output : 1

[Naive Approach] Using Nested Loops - O(n2 * log(n)) Time

A Naive approach is to run two loops one inside the other. Select all pairs one by one, find GCD of every pair and then find sum of these GCDs.

[Efficient Approach] Using Euler's Totient Function - O(MAX*log(log MAX)) Time and O(MAX) Space

The idea is to use Euler's Totient function Φ(n) for an input n is count of numbers in {1, 2, 3, ..., n} that are relatively prime to n, i.e., the numbers whose GCD (Greatest Common Divisor) with n is 1. For example, ?(4) = 2, ?(3) = 2 and ?(5) = 4. There are 2 numbers smaller or equal to 4 that are relatively prime to 4, 2 numbers smaller or equal to 3 that are relatively prime to 3. And 4 numbers smaller than or equal to 5 that are relatively prime to 5.

The idea is to convert given problem into sum of Euler Totient Functions.

Sum of all GCDs where j is a part of pair is and j is greater element in pair:
\text{Sum}_j = \sum_{i=1}^{j-1} \text{gcd}(i, j)

Our final result is \text{Result} = \sum_{j=1}^{N} \text{Sum}_j

The above equation can be written as :
\text{Sum}_j = \sum_{g} g \cdot \text{count}(g)

For every possible GCD 'g' of j. Here count(g) represents count of pairs having GCD equals to g. For every such pair(i, j), we can write : gcd(i/g, j/g) = 1

We can re-write our previous equation as
Sumj = ∑d * ϕ(j/d)
For every divisor d of j and phi[] is Euler Totient number

Example : j = 12 and d = 3 is one of divisor of j so in order to calculate the sum of count of all pairs having 3 as gcd we can simple write it as
=> 3*ϕ[12/3]
=> 3*ϕ[4]
=> 3*2
=> 6

Therefore sum of GCDs of all pairs where 12 is greater part of pair and 3 is GCD.
GCD(3, 12) + GCD(9, 12) = 6.

Complete Example :
N = 4
Sum1 = 0
Sum2 = 1 [GCD(1, 2)]
Sum3 = 2 [GCD(1, 3) + GCD(2, 3)]
Sum4 = 4 [GCD(1, 4) + GCD(3, 4) + GCD(2, 4)]

Result = Sum1 + Sum2 + Sum3 + Sum4
= 0 + 1 + 2 + 4
= 7

Below is the implementation of above idea. We pre-compute Euler Totient Functions and result for all numbers till a maximum value. The idea used in implementation is based this post.

C++
// C++ approach of finding sum of GCD of all pairs
#include<bits/stdc++.h>
using namespace std;

#define MAX 100001

// phi[i] stores euler totient function for i
// result[j] stores result for value j
long long phi[MAX], result[MAX];

// Precomputation of phi[] numbers. Refer below link
// for details : https://goo.gl/LUqdtY
void computeTotient()
{
    // Refer https://goo.gl/LUqdtY
    phi[1] = 1;
    for (int i=2; i<MAX; i++)
    {
        if (!phi[i])
        {
            phi[i] = i-1;
            for (int j = (i<<1); j<MAX; j+=i)
            {
                if (!phi[j])
                    phi[j] = j;

                phi[j] = (phi[j]/i)*(i-1);
            }
        }
    }
}

// Precomputes result for all numbers till MAX
void sumOfGcdPairs()
{
    // Precompute all phi value
    computeTotient();

    for (int i=1; i<MAX; ++i)
    {
        // Iterate through all the divisors
        // of i.
        for (int j=2; i*j<MAX; ++j)
            result[i*j] += i*phi[j];
    }

    // Add summation of previous calculated sum
    for (int i=2; i<MAX; i++)
        result[i] += result[i-1];
}

// Driver code
int main()
{
    // Function to calculate sum of all the GCD
    // pairs
    sumOfGcdPairs();

    int N = 4;
    cout << "Summation of " << N << " = "
         << result[N] << endl;;
    N = 12;
    cout << "Summation of " << N << " = "
        << result[N] << endl;
    N = 5000;
    cout << "Summation of " << N << " = "
        << result[N] ;

    return 0;
}
Java
// Java approach of finding 
// sum of GCD of all pairs.
import java.lang.*;

class GFG {
    
static final int MAX = 100001;

// phi[i] stores euler totient function for i
// result[j] stores result for value j
static long phi[] = new long[MAX];
static long result[] = new long[MAX];

// Precomputation of phi[] numbers.
// Refer below link for details :
// https://goo.gl/LUqdtY
static void computeTotient() {
    
    // Refer https://goo.gl/LUqdtY
    phi[1] = 1;
    for (int i = 2; i < MAX; i++) {
    if (phi[i] == 0) {
        phi[i] = i - 1;
        for (int j = (i << 1); j < MAX; j += i) {
        if (phi[j] == 0)
            phi[j] = j;

        phi[j] = (phi[j] / i) * (i - 1);
        }
    }
    }
}

// Precomputes result for all
// numbers till MAX
static void sumOfGcdPairs() {
    
    // Precompute all phi value
    computeTotient();

    for (int i = 1; i < MAX; ++i) {
        
    // Iterate throght all the 
    // divisors of i.
    for (int j = 2; i * j < MAX; ++j)
        result[i * j] += i * phi[j];
    }

    // Add summation of previous calculated sum
    for (int i = 2; i < MAX; i++)
    result[i] += result[i - 1];
}

// Driver code
public static void main(String[] args) {
    
    // Function to calculate sum of 
    // all the GCD pairs
    sumOfGcdPairs();

    int N = 4;
    System.out.println("Summation of " + N +
                         " = " + result[N]);
    N = 12;
    System.out.println("Summation of " + N + 
                         " = " + result[N]);
    N = 5000;
    System.out.print("Summation of " + N + 
                      " = " + +result[N]);
}
}
Python
# Python approach of finding
# sum of GCD of all pairs
MAX = 100001

# phi[i] stores euler 
# totient function for 
# i result[j] stores 
# result for value j
phi = [0] * MAX
result = [0] * MAX

# Precomputation of phi[]
# numbers. Refer below link
# for details : https://goo.gl/LUqdtY
def computeTotient():

    # Refer https://goo.gl/LUqdtY
    phi[1] = 1
    for i in range(2, MAX):
        if not phi[i]:
            phi[i] = i - 1
            for j in range(i << 1, MAX, i):
                if not phi[j]:
                    phi[j] = j
                phi[j] = ((phi[j] // i) * 
                          (i - 1))

# Precomputes result 
# for all numbers 
# till MAX
def sumOfGcdPairs():
    
    # Precompute all phi value
    computeTotient()

    for i in range(MAX):
        
        # Iterate throght all 
        # the divisors of i.
        for j in range(2, MAX):
            if i * j >= MAX:
                break
            result[i * j] += i * phi[j]

    # Add summation of 
    # previous calculated sum
    for i in range(2, MAX):
        result[i] += result[i - 1]

# Driver code
# Function to calculate 
# sum of all the GCD pairs
sumOfGcdPairs()

N = 4
print("Summation of",N,"=",result[N])
N = 12
print("Summation of",N,"=",result[N])
N = 5000
print("Summation of",N,"=",result[N])
C#
// C# approach of finding 
// sum of GCD of all pairs.
using System;

class GFG {
    
static int MAX = 100001;

// phi[i] stores euler totient
// function for i result[j]
// stores result for value j
static long []phi = new long[MAX];
static long []result = new long[MAX];

// Precomputation of phi[] numbers.
// Refer below link for details :
// https://goo.gl/LUqdtY
static void computeTotient() {
    
    // Refer https://goo.gl/LUqdtY
    phi[1] = 1;
    for (int i = 2; i < MAX; i++) {
    if (phi[i] == 0) {
        phi[i] = i - 1;
        for (int j = (i << 1); j < MAX; j += i) {
        if (phi[j] == 0)
            phi[j] = j;

        phi[j] = (phi[j] / i) * (i - 1);
        }
    }
    }
}

// Precomputes result for all
// numbers till MAX
static void sumOfGcdPairs() {
    
    // Precompute all phi value
    computeTotient();

    for (int i = 1; i < MAX; ++i) {
        
    // Iterate throght all the 
    // divisors of i.
    for (int j = 2; i * j < MAX; ++j)
        result[i * j] += i * phi[j];
    }

    // Add summation of previous 
    // calculated sum
    for (int i = 2; i < MAX; i++)
    result[i] += result[i - 1];
}

// Driver code
public static void Main() {
    
    // Function to calculate sum of 
    // all the GCD pairs
    sumOfGcdPairs();

    int N = 4;
    Console.WriteLine("Summation of " + N +
                      " = " + result[N]);
    N = 12;
    Console.WriteLine("Summation of " + N + 
                      " = " + result[N]);
    N = 5000;
    Console.Write("Summation of " + N + 
                  " = " + +result[N]);
}
}
JavaScript
// JavaScript approach of finding sum of GCD of all pairs

// phi[i] stores euler totient function for i
// result[j] stores result for value j
let MAX = 100001;
let phi = new Array(MAX).fill(0);
let result = new Array(MAX).fill(0);

// Precomputation of phi[] numbers. Refer below link
// for details : https://goo.gl/LUqdtY
function computeTotient()
{
    // Refer https://goo.gl/LUqdtY
    phi[1] = 1;
    for (let i = 2; i < MAX; i++) {
        if (!phi[i]) {
            phi[i] = i - 1;
            for (let j = (i << 1); j < MAX; j += i) {
                if (!phi[j]) {
                    phi[j] = j;
                }
                phi[j] = (phi[j] / i) * (i - 1);
            }
        }
    }
}

// Precomputes result for all numbers till MAX
function sumOfGcdPairs()
{
    // Precompute all phi value
    computeTotient();

    for (let i = 1; i < MAX; ++i) {
        // Iterate throght all the divisors
        // of i.
        for (let j = 2; i * j < MAX; ++j) {
            result[i * j] += i * phi[j];
        }
    }

    // Add summation of previous calculated sum
    for (let i = 2; i < MAX; i++) {
        result[i] += result[i - 1];
    }
}

// Function to calculate sum of all the GCD
// pairs
sumOfGcdPairs();

let N = 4;
console.log("Summation  of ", N, " = ", result[N]);

N = 12;
console.log("Summation of ", N, " = ", result[N]);

N = 5000;
console.log("Summation of ", N, " = ", result[N]);
PHP
<?php
// PHP approach of finding sum of 
// GCD of all pairs

$MAX = 100001;

// phi[i] stores euler totient function for i
// result[j] stores result for value j
$phi = array_fill(0, $MAX, 0);
$result = array_fill(0, $MAX, 0);

// Precomputation of phi[] numbers. Refer 
// link for details : https://goo.gl/LUqdtY
function computeTotient()
{
    global $MAX, $phi;
    
    // Refer https://goo.gl/LUqdtY
    $phi[1] = 1;
    for ($i = 2; $i < $MAX; $i++)
    {
        if (!$phi[$i])
        {
            $phi[$i] = $i - 1;
            for ($j = ($i << 1); $j < $MAX; $j += $i)
            {
                if (!$phi[$j])
                    $phi[$j] = $j;

                $phi[$j] = ($phi[$j] / $i) * ($i - 1);
            }
        }
    }
}

// Precomputes result for all 
// numbers till MAX
function sumOfGcdPairs()
{
    global $MAX, $phi, $result;
    
    // Precompute all phi value
    computeTotient();

    for ($i = 1; $i < $MAX; ++$i)
    {
        // Iterate throght all the divisors
        // of i.
        for ($j = 2; $i * $j < $MAX; ++$j)
            $result[$i * $j] += $i * $phi[$j];
    }

    // Add summation of previous calculated sum
    for ($i = 2; $i < $MAX; $i++)
        $result[$i] += $result[$i - 1];
}

// Driver code

// Function to calculate sum of 
// all the GCD pairs
sumOfGcdPairs();

$N = 4;
echo "Summation of " . $N . 
     " = " . $result[$N] . "\n";
$N = 12;
echo "Summation of " . $N . 
     " = " . $result[$N] . "\n";
$N = 5000;
echo "Summation of " . $N . 
     " = " . $result[$N] . "\n";

Output
Summation of 4 = 7
Summation of 12 = 105
Summation of 5000 = 61567426

Time complexity: O(MAX*log(log MAX))
Auxiliary space: O(MAX)


Next Article
Article Tags :
Practice Tags :

Similar Reads