Summation of GCD of all the pairs up to N
Last Updated :
13 Sep, 2023
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:
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++
#include<bits/stdc++.h>
using namespace std;
#define MAX 100001
long long phi[MAX], result[MAX];
void computeTotient()
{
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);
}
}
}
}
void sumOfGcdPairs()
{
computeTotient();
for ( int i=1; i<MAX; ++i)
{
for ( int j=2; i*j<MAX; ++j)
result[i*j] += i*phi[j];
}
for ( int i=2; i<MAX; i++)
result[i] += result[i-1];
}
int main()
{
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
import java.lang.*;
class GFG {
static final int MAX = 100001 ;
static long phi[] = new long [MAX];
static long result[] = new long [MAX];
static void computeTotient() {
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 );
}
}
}
}
static void sumOfGcdPairs() {
computeTotient();
for ( int i = 1 ; i < MAX; ++i) {
for ( int j = 2 ; i * j < MAX; ++j)
result[i * j] += i * phi[j];
}
for ( int i = 2 ; i < MAX; i++)
result[i] += result[i - 1 ];
}
public static void main(String[] args) {
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]);
}
}
|
Python3
MAX = 100001
phi = [ 0 ] * MAX
result = [ 0 ] * MAX
def computeTotient():
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 ))
def sumOfGcdPairs():
computeTotient()
for i in range ( MAX ):
for j in range ( 2 , MAX ):
if i * j > = MAX :
break
result[i * j] + = i * phi[j]
for i in range ( 2 , MAX ):
result[i] + = result[i - 1 ]
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#
using System;
class GFG {
static int MAX = 100001;
static long []phi = new long [MAX];
static long []result = new long [MAX];
static void computeTotient() {
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);
}
}
}
}
static void sumOfGcdPairs() {
computeTotient();
for ( int i = 1; i < MAX; ++i) {
for ( int j = 2; i * j < MAX; ++j)
result[i * j] += i * phi[j];
}
for ( int i = 2; i < MAX; i++)
result[i] += result[i - 1];
}
public static void Main() {
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]);
}
}
|
PHP
<?php
$MAX = 100001;
$phi = array_fill (0, $MAX , 0);
$result = array_fill (0, $MAX , 0);
function computeTotient()
{
global $MAX , $phi ;
$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);
}
}
}
}
function sumOfGcdPairs()
{
global $MAX , $phi , $result ;
computeTotient();
for ( $i = 1; $i < $MAX ; ++ $i )
{
for ( $j = 2; $i * $j < $MAX ; ++ $j )
$result [ $i * $j ] += $i * $phi [ $j ];
}
for ( $i = 2; $i < $MAX ; $i ++)
$result [ $i ] += $result [ $i - 1];
}
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" ;
?>
|
JavaScript
<script>
let MAX = 100001;
let phi = new Array(MAX).fill(0);
let result = new Array(MAX).fill(0);
function computeTotient()
{
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);
}
}
}
}
function sumOfGcdPairs()
{
computeTotient();
for (let i=1; i<MAX; ++i)
{
for (let j=2; i*j<MAX; ++j)
{
result[i*j] += i*phi[j];
}
}
for (let i=2; i<MAX; i++)
{
result[i] += result[i-1];
}
}
{
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]);
}
</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
Share your thoughts in the comments
Please Login to comment...