Open In App

Summation of GCD of all the pairs up to N

Last Updated : 13 Sep, 2023
Improve
Improve
Like Article
Like
Save
Share
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  : 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++




    // 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 :
    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]);
    }
    }
      
    // This code is contributed by Anant Agarwal.

    
    

    Python3




    # 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])
      
    # 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 j
    static long []phi = new long[MAX];
    static long []result = new long[MAX];
      
    // Precomputation of phi[] numbers.
    // Refer below link for details :
    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]);
    }
    }
      
    // 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/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";
      
    // This code is contributed by mits
    ?>

    
    

    JavaScript




    <script>
    // 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];
        }
              
    }
      
    // Driver code
    {
        // 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]);
      
    }
      
    // The code is contributed by Gautam  goel (gautamgoel962)
    </script>

    
    

    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



    Like Article
    Suggest improvement
    Previous
    Next
    Share your thoughts in the comments

Similar Reads