Summation of GCD of all the pairs up to n
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++ 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 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 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# 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 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 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)