Summation of GCD of all the pairs up to N - GeeksforGeeks

27 Dec, 2018
Given a number N, find sum of all GCDs that can be formed by selecting all the pairs from 1 to N.Examples:
Input  : 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  : 12
Output : 105

Input  : 1
Output : 0

Input  : 2
Output : 1

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. Time complexity of this approach is O(N2 * log(N))
Efficient Approach is based on following concepts:
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:
Sumj = ?(i=1 to j-1) gcd(i, j)
Our final result is 
Result = ?(j=1 to N) Sumj

The above equation can be written as :
Sumj = ? g * 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 * phi(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*phi[12/3]  
=> 3*phi[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++JavaPython3C#PHPC++// 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 jlong long phi[MAX], result[MAX];  // Precomputation of phi[] numbers. Refer below link// for details : https://goo.gl/LUqdtYvoid 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 MAXvoid 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 codeint 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 jstatic long phi[] = new long[MAX];static long result[] = new long[MAX];  // Precomputation of phi[] numbers.// Refer below link for details :// https://goo.gl/LUqdtYstatic 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 MAXstatic 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 codepublic 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]);}}  // This code is contributed by Anant Agarwal.Python3# Python approach of finding# sum of GCD of all pairsMAX = 100001  # phi[i] stores euler # totient function for # i result[j] stores # result for value jphi = [0] * MAXresult = [0] * MAX  # Precomputation of phi[]# numbers. Refer below link# for details : https://goo.gl/LUqdtYdef 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 MAXdef 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 pairssumOfGcdPairs()  N = 4print("Summation of",N,"=",result[N])N = 12print("Summation of",N,"=",result[N])N = 5000print("Summation of",N,"=",result[N])  # This code is contributed # by Sanjit_Prasad.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 jstatic long []phi = new long[MAX];static long []result = new long[MAX];  // Precomputation of phi[] numbers.// Refer below link for details :// https://goo.gl/LUqdtYstatic 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 MAXstatic 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 codepublic 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]);}}  // This code is contributed by Nitin Mittal.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/LUqdtYfunction 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 MAXfunction 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 pairssumOfGcdPairs();  $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";  // This code is contributed by mits?>Output:Summation of 4 = 7
Summation of 12 = 105
Summation of 5000 = 61567426
Time complexity: O(MAX*log(log MAX))Auxiliary space: O(MAX)Reference:https://www.quora.com/How-can-I-solve-the-problem-GCD-Extreme-on-SPOJ-SPOJ-com-Problem-GCDEXThis article is contributed by Shubham Bansal. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.My Personal Notes
arrow_drop_upSave
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:
Sumj = ?(i=1 to j-1) gcd(i, j)
Our final result is 
Result = ?(j=1 to N) Sumj

The above equation can be written as :
Sumj = ? g * 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 * phi(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*phi[12/3]  
=> 3*phi[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++
Java
Python3
C#
PHP
// 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 jlong long phi[MAX], result[MAX];  // Precomputation of phi[] numbers. Refer below link// for details : https://goo.gl/LUqdtYvoid 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 MAXvoid 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 codeint 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 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 jstatic long phi[] = new long[MAX];static long result[] = new long[MAX];  // Precomputation of phi[] numbers.// Refer below link for details :// https://goo.gl/LUqdtYstatic 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 MAXstatic 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 codepublic 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]);}}  // This code is contributed by Anant Agarwal.
# Python approach of finding# sum of GCD of all pairsMAX = 100001  # phi[i] stores euler # totient function for # i result[j] stores # result for value jphi = [0] * MAXresult = [0] * MAX  # Precomputation of phi[]# numbers. Refer below link# for details : https://goo.gl/LUqdtYdef 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 MAXdef 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 pairssumOfGcdPairs()  N = 4print("Summation of",N,"=",result[N])N = 12print("Summation of",N,"=",result[N])N = 5000print("Summation of",N,"=",result[N])  # This code is contributed # by Sanjit_Prasad.
// 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 jstatic long []phi = new long[MAX];static long []result = new long[MAX];  // Precomputation of phi[] numbers.// Refer below link for details :// https://goo.gl/LUqdtYstatic 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 MAXstatic 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 codepublic 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]);}}  // This code is contributed by Nitin Mittal.
<?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/LUqdtYfunction 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 MAXfunction 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 pairssumOfGcdPairs();  $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";  // This code is contributed by mits?>
Output:
Summation of 4 = 7
Summation of 12 = 105
Summation of 5000 = 61567426

Time complexity: O(MAX*log(log MAX))Auxiliary space: O(MAX)
Reference:https://www.quora.com/How-can-I-solve-the-problem-GCD-Extreme-on-SPOJ-SPOJ-com-Problem-GCDEX
This article is contributed by Shubham Bansal. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
nitin mittal
Sanjit_Prasad
Mithun Kumar
GCD-LCM
Mathematical
Mathematical
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Merge two sorted arrays
Modulo Operator (%) in C/C++ with Examples
Prime Numbers
Print all possible combinations of r elements in a given array of size n
Program for Decimal to Binary Conversion
The Knight's tour problem | Backtracking-1
Operators in C / C++
Program for factorial of a number
Find minimum number of coins that make a given value
Program to find sum of elements in a given array