Open In App

Number of co-prime pairs in an array

Last Updated : 14 Jul, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Given an array arr[], count the number of pairs (i, j) such that i < j and gcd(arr[i], arr[j]) == 1.

Examples:  

Input : arr[] = [1, 2, 3]
Output : 3
Explanation : Here, Co-prime pairs are (1, 2), (2, 3), (1, 3) .

Input : arr[] = [4, 8, 3, 9]
Output : 4
Explanation : Here, Co-prime pairs are (4, 3), (8, 3), (4, 9), (8, 9).

[Naive Approach] Using Two Loop

This approach checks all possible pairs in the array using two nested loops and counts those whose GCD is 1, indicating they are co-prime.

C++
#include <iostream>
#include <vector>
#include <algorithm>   
using namespace std;

// Function to check if two numbers are co-prime
int gcd(int a, int b) {
    if (b == 0) return a;
    return gcd(b, a % b);
}

// Function to count number of co-prime 
// pairs in the array
int cntCoprime(vector<int>& arr) {
    int n = arr.size(), count = 0;

    // Check all unique pairs (i, j) such that i < j
    for (int i = 0; i < n - 1; ++i) {
        for (int j = i + 1; j < n; ++j) {
            if (gcd(arr[i], arr[j]) == 1) {
                count++;
            }
        }
    }

    return count;
}

int main() {
    
    vector<int> arr = {4, 8, 3, 9};
    cout << cntCoprime(arr) << endl;
    return 0;
    
}
Java
import java.util.*;

class GfG {

    // Function to compute GCD
    static int gcd(int a, int b) {
        if (b == 0) return a;
        return gcd(b, a % b);
    }

    // Function to count co-prime pairs
    public static int cntCoprime(int[] arr) {
        int n = arr.length, count = 0;

        for (int i = 0; i < n - 1; ++i) {
            for (int j = i + 1; j < n; ++j) {
                if (gcd(arr[i], arr[j]) == 1) {
                    count++;
                }
            }
        }
        return count;
    }

    public static void main(String[] args) {
        int[] arr = {4, 8, 3, 9};
        System.out.println(cntCoprime(arr));
    }
}
Python
import math

# Function to compute GCD
def gcd(a, b):
    if b == 0:
        return a
    return gcd(b, a % b)
# Function to count co-prime pairs
def cntCoprime(arr):
    n = len(arr)
    count = 0
    for i in range(n - 1):
        for j in range(i + 1, n):
            if gcd(arr[i], arr[j]) == 1:
                count += 1
    return count


if __name__ == "__main__":
    arr = [4, 8, 3, 9]
    print(cntCoprime(arr))
C#
using System;

class GfG {
    // Function to compute GCD
    static int gcd(int a, int b) {
        while (b != 0) {
            int temp = b;
            b = a % b;
            a = temp;
        }
        return a;
    }

    // Function to count co-prime pairs
    public static int cntCoprime(int[] arr) {
        int count = 0;
        int n = arr.Length;

        for (int i = 0; i < n - 1; i++) {
            for (int j = i + 1; j < n; j++) {
                if (gcd(arr[i], arr[j]) == 1)
                    count++;
            }
        }
        return count;
    }

    public static void Main() {
        int[] arr = { 4, 8, 3, 9 };
        Console.WriteLine(cntCoprime(arr));
    }
}
JavaScript
// Function to compute GCD
function gcd(a, b) {
    while (b !== 0) {
        [a, b] = [b, a % b];
    }
    return a;
}

// Function to count co-prime pairs
function cntCoprime(arr) {
    let count = 0;
    const n = arr.length;

    for (let i = 0; i < n - 1; i++) {
        for (let j = i + 1; j < n; j++) {
            if (gcd(arr[i], arr[j]) === 1) {
                count++;
            }
        }
    }

    return count;
}

// Driver code
const arr = [4, 8, 3, 9];
console.log(cntCoprime(arr));

Output
4

Time Complexity: O(n2 × log(m)),where m = max(arr[i])
Space Complexity: O(log(m)), where m = max(arr[i])

[Expected Approach] Using Mobius Function

Instead of directly counting coprime pairs, which can be inefficient, we count how many pairs share a common divisor k and then apply the Inclusion-Exclusion Principle using the Möbius function to isolate only those with gcd = 1.

For each k, we compute d(k), the number of elements divisible by k, and use d(k)*(d(k)-1) / 2 to count such pairs. However, this includes overlaps, so the Möbius function {\scriptstyle \mu(k)} is used to adjust these counts: if it is 1 if k is a product of an even number of distinct primes, –1 if odd, and 0 if k has any squared prime factor.

Finally, we sum the adjusted values as \scriptsize\sum_{k=1}^{\max(arr[i])} \mu(k) \cdot \binom{d(k)}{2}to get the total number of coprime pairs

Step by Step Implementations:

  • Count frequency of each number in the array freq[]
  • Compute d(k) for every k from 1 to max(arr[i])
    • d(k) is the number of elements divisible by k
    • Use a sieve-style loop: for each k, add up freq[j] for all j divisible by k.
  • Precompute the Möbius function μ(k) up to max(arr[i])
    • Use a modified Sieve of Eratosthenes:
      • Set μ(1) = 1
      • For each prime p, update multiples:
      – Flip sign of μ(k) for each multiple of p
      – Set μ(k) = 0 for multiples of p^2
  • Apply the Möbius formula using Inclusion-Exclusion: {\scriptsize \text{Number of coprime pairs} = \sum_{k=1}^{\max(arr[i])} \mu(k) \cdot \binom{d(k)}{2} }
    • Only square-free k (i.e., with non-zero μ) contribute.
  • Sum up the contributions from all valid k to get the final answer
C++
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

// Computes the Möbius function up to 'n'
void computeMobius(int n, vector<int>& mu) {
    vector<int> is_prime(n + 1, 1);
    mu[0] = 0;
    mu[1] = 1;

    for (int i = 2; i <= n; ++i) {
        if (is_prime[i]) {
            for (int j = i; j <= n; j += i) {
                mu[j] *= -1;
                is_prime[j] = 0;
            }
            
            // Not square-free
            for (int j = i * i; j <= n; j += i * i) {
                mu[j] = 0; 
            }
        }
    }
}

// Builds frequency array for values in 'arr'
void buildFre(vector<int>& arr, vector<int>& freq) {
    for (int x : arr)
        freq[x]++;
}

// For each k, computes how many numbers in arr 
// are divisible by k
void computeDivCnt(int maxVal, vector<int>& freq, vector<int>& d) {
    for (int k = 1; k <= maxVal; ++k)
        for (int j = k; j <= maxVal; j += k)
            d[k] += freq[j];
}

// logic to count coprime pairs using 
// Möbius and Inclusion-Exclusion
int cntCoprime(vector<int>& arr) {

    int maxVal = *max_element(arr.begin(), arr.end());
    
    // d[i] -> number of elements divisible by 'i'
    // mu[i] -> mobius sign for 'i'
    // fre[i] -> frequency of element 'i'
    vector<int> freq(maxVal + 1, 0), d(maxVal + 1, 0), mu(maxVal + 1, 1);
    
    buildFre(arr, freq);
    computeDivCnt(maxVal, freq, d);
    computeMobius(maxVal, mu);

    int result = 0;
    for (int k = 1; k <= maxVal; ++k) {
        if (mu[k] == 0 || d[k] < 2) continue;
    
        // number of pairs that are divisible by k
        int pairs = d[k] * (d[k] - 1) / 2;
        result += mu[k] * pairs;
    }

    return result;
}

int main() {

    vector<int> arr = {4, 8, 3, 9};
    cout << cntCoprime(arr) << endl;

    return 0;
}
Java
import java.util.*;

class GfG {

    // Computes the Möbius function up to 'n'
    static void computeMobius(int n, int[] mu) {
        int[] is_prime = new int[n + 1];
        Arrays.fill(is_prime, 1);
        mu[0] = 0;
        mu[1] = 1;

        for (int i = 2; i <= n; ++i) {
            if (is_prime[i] == 1) {
                for (int j = i; j <= n; j += i) {
                    mu[j] *= -1;
                    is_prime[j] = 0;
                }
                // Not square-free
                for (int j = i * i; j <= n; j += i * i) {
                    mu[j] = 0;
                }
            }
        }
    }

    // Builds frequency array for values in 'arr'
    static void buildFre(int[] arr, int[] freq) {
        for (int x : arr)
            freq[x]++;
    }

    // For each k, computes how many numbers in arr 
    // are divisible by k
    static void computeDivCnt(int maxVal, int[] freq, int[] d) {
        for (int k = 1; k <= maxVal; ++k)
            for (int j = k; j <= maxVal; j += k)
                d[k] += freq[j];
    }

    // logic to count coprime pairs using 
    // Möbius and Inclusion-Exclusion
    static int cntCoprime(int[] arr) {

        int maxVal = Arrays.stream(arr).max().getAsInt();
        
        // d[i] -> number of elements divisible by 'i'
        // mu[i] -> mobius sign for 'i'
        // fre[i] -> frequency of element 'i'
        int[] freq = new int[maxVal + 1];
        int[] d = new int[maxVal + 1];
        int[] mu = new int[maxVal + 1];
        Arrays.fill(mu, 1);

        buildFre(arr, freq);
        computeDivCnt(maxVal, freq, d);
        computeMobius(maxVal, mu);

        int result = 0;
        for (int k = 1; k <= maxVal; ++k) {
            if (mu[k] == 0 || d[k] < 2) continue;
            
            // number of pairs that are divisible by k
            int pairs = (int)((d[k] * (d[k] - 1)) / 2);
            result += mu[k] * pairs;
        }

        return result;
    }

    public static void main(String[] args) {
        int[] arr = {4, 8, 3, 9};
        System.out.println(cntCoprime(arr));
    }
}
Python
# Computes the Möbius function up to 'n'
def computeMobius(n, mu):
    is_prime = [1] * (n + 1)
    mu[0] = 0
    mu[1] = 1

    for i in range(2, n + 1):
        if is_prime[i]:
            for j in range(i, n + 1, i):
                mu[j] *= -1
                is_prime[j] = 0
            # Not square-free
            for j in range(i * i, n + 1, i * i):
                mu[j] = 0

# Builds frequency array for values in 'arr'
def buildFre(arr, freq):
    for x in arr:
        freq[x] += 1

# For each k, computes how many numbers in arr 
# are divisible by k
def computeDivCnt(maxVal, freq, d):
    for k in range(1, maxVal + 1):
        for j in range(k, maxVal + 1, k):
            d[k] += freq[j]

# logic to count coprime pairs using 
# Möbius and Inclusion-Exclusion
def cntCoprime(arr):
    maxVal = max(arr)
    
    # d[i] -> number of elements divisible by 'i'
    # mu[i] -> mobius sign for 'i'
    # fre[i] -> frequency of element 'i'
    
    freq = [0] * (maxVal + 1)
    d = [0] * (maxVal + 1)
    mu = [1] * (maxVal + 1)

    buildFre(arr, freq)
    computeDivCnt(maxVal, freq, d)
    computeMobius(maxVal, mu)

    result = 0
    for k in range(1, maxVal + 1):
        if mu[k] == 0 or d[k] < 2:
            continue
        
        # number of pairs that are divisible by k
        pairs = d[k] * (d[k] - 1) // 2
        result += mu[k] * pairs

    return result

if __name__ == "__main__":
    arr = [4, 8, 3, 9]
    print(cntCoprime(arr))
C#
using System;
using System.Linq;

class GfG
{
    // Computes the Möbius function up to 'n'
    static void computeMobius(int n, int[] mu)
    {
        int[] is_prime = new int[n + 1];
        Array.Fill(is_prime, 1);
        mu[0] = 0;
        mu[1] = 1;

        for (int i = 2; i <= n; ++i)
        {
            if (is_prime[i] == 1)
            {
                for (int j = i; j <= n; j += i)
                {
                    mu[j] *= -1;
                    is_prime[j] = 0;
                }
                // Not square-free
                for (int j = i * i; j <= n; j += i * i)
                {
                    mu[j] = 0;
                }
            }
        }
    }

    // Builds frequency array for values in 'arr'
    static void buildFre(int[] arr, int[] freq)
    {
        foreach (int x in arr)
            freq[x]++;
    }

    // For each k, computes how many numbers in arr 
    // are divisible by k
    static void computeDivCnt(int maxVal, int[] freq, int[] d)
    {
        for (int k = 1; k <= maxVal; ++k)
            for (int j = k; j <= maxVal; j += k)
                d[k] += freq[j];
    }

    // logic to count coprime pairs using 
    // Möbius and Inclusion-Exclusion
    static int cntCoprime(int[] arr)
    {
        int maxVal = arr.Max();
        
        // d[i] -> number of elements divisible by 'i'
        // mu[i] -> mobius sign for 'i'
        // fre[i] -> frequency of element 'i'
        int[] freq = new int[maxVal + 1];
        int[] d = new int[maxVal + 1];
        int[] mu = Enumerable.Repeat(1, maxVal + 1).ToArray();

        buildFre(arr, freq);
        computeDivCnt(maxVal, freq, d);
        computeMobius(maxVal, mu);

        int result = 0;
        for (int k = 1; k <= maxVal; ++k)
        {
            if (mu[k] == 0 || d[k] < 2) continue;
            
            // number of pairs that are divisible by k
            int pairs = (int)(d[k] * (d[k] - 1) / 2);
            result += mu[k] * pairs;
        }

        return result;
    }

    // Driver Code
    public static void Main()
    {
        int[] arr = { 4, 8, 3, 9 };
        Console.WriteLine(cntCoprime(arr));
    }
}
JavaScript
// Computes the Möbius function up to 'n'
function computeMobius(n, mu) {
    let is_prime = new Array(n + 1).fill(1);
    mu[0] = 0;
    mu[1] = 1;

    for (let i = 2; i <= n; ++i) {
        if (is_prime[i]) {
            for (let j = i; j <= n; j += i) {
                mu[j] *= -1;
                is_prime[j] = 0;
            }
            // Not square-free
            for (let j = i * i; j <= n; j += i * i) {
                mu[j] = 0;
            }
        }
    }
}

// Builds frequency array for values in 'arr'
function buildFre(arr, freq) {
    for (let x of arr)
        freq[x]++;
}

// For each k, computes how many numbers in arr 
// are divisible by k
function computeDivCnt(maxVal, freq, d) {
    for (let k = 1; k <= maxVal; ++k)
        for (let j = k; j <= maxVal; j += k)
            d[k] += freq[j];
}

// logic to count coprime pairs using 
// Möbius and Inclusion-Exclusion
function cntCoprime(arr) {
    const maxVal = Math.max(...arr);
    
    // d[i] -> number of elements divisible by 'i'
    // mu[i] -> mobius sign for 'i'
    // fre[i] -> frequency of element 'i'
    const freq = new Array(maxVal + 1).fill(0);
    const d = new Array(maxVal + 1).fill(0);
    const mu = new Array(maxVal + 1).fill(1);

    buildFre(arr, freq);
    computeDivCnt(maxVal, freq, d);
    computeMobius(maxVal, mu);

    let result = 0;
    for (let k = 1; k <= maxVal; ++k) {
        if (mu[k] === 0 || d[k] < 2) continue;
        
        // number of pairs that are divisible by k
        let pairs = (d[k] * (d[k] - 1)) / 2;
        result += mu[k] * pairs;
    }

    return result;
}

// Driver Code
const arr = [4, 8, 3, 9];
console.log(cntCoprime(arr));

Output
4

Time Complexity: O(n + m*log(m)), building divisor counts and computing the Möbius function both take O(m log⁡(m)), where m = max(arr[i])
Space Complexity: O(m), where m = max⁡(arr[i]).


Similar Reads