Open In App

Count pairs whose product contains single distinct prime factor

Given an array arr[] of size N, the task is to count the number of pairs from the given array whose product contains only a single distinct prime factor.

Examples:



Input: arr[] = {1, 2, 3, 4}
Output: 4
Explanation: 
Pairs having single distinct prime factor in their product is as follows: 
arr[0] * arr[1] = (1 * 2) = 2. Therefore, the single distinct prime factor is 2. 
arr[0] * arr[2] = (1 * 3) = 3. Therefore, the single distinct prime factor is 3. 
arr[0] * arr[3] = (1 * 4) = 22 Therefore, the single distinct prime factor is 2. 
arr[1] * arr[3] = (2 * 4) = 8 23 Therefore, the single distinct prime factor is 2. 
Therefore, the required output is 4.

Input: arr[] = {2, 4, 6, 8}
Output: 3



Naive Approach: The simplest approach to solve this problem is to traverse the array and generate all possible pairs of the array and for each pair, check if the product of elements contains only a single distinct prime factor or not. If found to be true, then increment the count. Finally, print the count.

Time Complexity: O(N2 * √X), where X is the maximum possible product of a pair in the given array.
Auxiliary Space: O(1)

Efficient Approach: To optimize the above approach the idea is to use Hashing. Follow the steps below to solve the problem:

Below is the implementation of the above approach




// C++ program to implement
// the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to find a single
// distinct prime factor of N
int singlePrimeFactor(int N)
{
 
    // Stores distinct
    // prime factors of N
    unordered_set<int> disPrimeFact;
 
    // Calculate prime factor of N
    for (int i = 2; i * i <= N; ++i) {
 
        // Calculate distinct
        // prime factor
        while (N % i == 0) {
 
            // Insert i into
            // disPrimeFact
            disPrimeFact.insert(i);
 
            // Update N
            N /= i;
        }
    }
 
    // If N is not equal to 1
    if (N != 1) {
 
        // Insert N into
        // disPrimeFact
        disPrimeFact.insert(N);
    }
 
    // If N contains a single
    // distinct prime factor
    if (disPrimeFact.size() == 1) {
 
        // Return single distinct
        // prime factor of N
        return *disPrimeFact.begin();
    }
 
    // If N contains more than one
    // distinct prime factor
    return -1;
}
 
// Function to count pairs in the array
// whose product contains only
// single distinct prime factor
int cntsingleFactorPair(int arr[], int N)
{
 
    // Stores count of 1s
    // in the array
    int countOf1 = 0;
 
    // mp[i]: Stores count of array elements
    // whose distinct prime factor is only i
    unordered_map<int, int> mp;
 
    // Traverse the array arr[]
    for (int i = 0; i < N; i++) {
 
        // If current element is 1
        if (arr[i] == 1) {
            countOf1++;
            continue;
        }
 
        // Store distinct
        // prime factor of arr[i]
        int factorValue = singlePrimeFactor(arr[i]);
 
        // If arr[i] contains more
        // than one prime factor
        if (factorValue == -1) {
            continue;
        }
 
        // If arr[i] contains
        // a single prime factor
        else {
            mp[factorValue]++;
        }
    }
 
    // Stores the count of pairs whose
    // product of elements contains only
    // a single distinct prime factor
    int res = 0;
 
    // Traverse the map mp[]
    for (auto it : mp) {
 
        // Stores count of array elements
        // whose prime factor is (it.first)
        int X = it.second;
 
        // Update res
        res += countOf1 * X + (X * (X - 1)) / 2;
    }
 
    return res;
}
 
// Driver Code
int main()
{
 
    int arr[] = { 1, 2, 3, 4 };
    int N = sizeof(arr) / sizeof(arr[0]);
    cout << cntsingleFactorPair(arr, N);
 
    return 0;
}




// Java program to implement
// the above approach
import java.util.*;
class GFG{
 
// Function to find a single
// distinct prime factor of N
static int singlePrimeFactor(int N)
{
  // Stores distinct
  // prime factors of N
  HashSet<Integer> disPrimeFact =
                   new HashSet<>();
 
  // Calculate prime factor of N
  for (int i = 2;
           i * i <= N; ++i)
  {
    // Calculate distinct
    // prime factor
    while (N % i == 0)
    {
      // Insert i into
      // disPrimeFact
      disPrimeFact.add(i);
 
      // Update N
      N /= i;
    }
  }
 
  // If N is not equal to 1
  if (N != 1)
  {
    // Insert N into
    // disPrimeFact
    disPrimeFact.add(N);
  }
 
  // If N contains a single
  // distinct prime factor
  if (disPrimeFact.size() == 1)
  {
    // Return single distinct
    // prime factor of N
    for(int i : disPrimeFact)
      return i;
  }
 
  // If N contains more than
  // one distinct prime factor   
  return -1;
}
 
 
// Function to count pairs in
// the array whose product
// contains only single distinct
// prime factor
static int cntsingleFactorPair(int arr[],
                               int N)
{  
  // Stores count of 1s
  // in the array
  int countOf1 = 0;
 
  // mp[i]: Stores count of array
  // elements whose distinct prime
  // factor is only i
  HashMap<Integer,
          Integer> mp = new HashMap<Integer,
                                    Integer>();
 
  // Traverse the array arr[]
  for (int i = 0; i < N; i++)
  {
    // If current element is 1
    if(arr[i] == 1)
    {
      countOf1++;
      continue;
    }
 
    // Store distinct
    // prime factor of arr[i]
    int factorValue =
        singlePrimeFactor(arr[i]);
 
    // If arr[i] contains more
    // than one prime factor
    if (factorValue == -1)
    {
      continue;
    }
 
    // If arr[i] contains
    // a single prime factor
    else
    {
      if(mp.containsKey(factorValue))
        mp.put(factorValue,
        mp.get(factorValue) + 1);
      else
        mp.put(factorValue, 1);
    }
  }
 
  // Stores the count of pairs whose
  // product of elements contains only
  // a single distinct prime factor
  int res = 0;
 
  // Traverse the map mp[]
  for (Map.Entry<Integer,
                 Integer> it :
       mp.entrySet())
  {
    // Stores count of array
    // elements whose prime
    // factor is (it.first)
    int X = it.getValue();
 
    // Update res
    res += countOf1 * X +
           (X * (X - 1) ) / 2;
  }
 
  return res;
}
 
// Driver Code
public static void main(String[] args)
{
  int arr[] = {1, 2, 3, 4};
  int N = arr.length;
  System.out.print(
         cntsingleFactorPair(arr, N));
}
}
 
// This code is contributed by gauravrajput1




# Python3 program to implement
# the above approach
 
# Function to find a single
# distinct prime factor of N
def singlePrimeFactor(N):
     
    # Stores distinct
    # prime factors of N
    disPrimeFact = {}
     
    # Calculate prime factor of N
    for i in range(2, N + 1):
        if i * i > N:
            break
         
        # Calculate distinct
        # prime factor
        while (N % i == 0):
             
            # Insert i into
            # disPrimeFact
            disPrimeFact[i] = 1
             
            # Update N
            N //= i
 
    # If N is not equal to 1
    if (N != 1):
         
        # Insert N into
        # disPrimeFact
        disPrimeFact[N] = 1
         
    # If N contains a single
    # distinct prime factor
    if (len(disPrimeFact) == 1):
         
        # Return single distinct
        # prime factor of N
        return list(disPrimeFact.keys())[0]
         
    # If N contains more than one
    # distinct prime factor
    return -1
 
# Function to count pairs in the array
# whose product contains only
# single distinct prime factor
def cntsingleFactorPair(arr, N):
     
    # Stores count of 1s
    # in the array
    countOf1 = 0
 
    # mp[i]: Stores count of array elements
    # whose distinct prime factor is only i
    mp = {}
 
    # Traverse the array arr[]
    for i in range(N):
         
        # If current element is 1
        if (arr[i] == 1):
            countOf1 += 1
            continue
 
        # Store distinct
        # prime factor of arr[i]
        factorValue = singlePrimeFactor(arr[i])
 
        # If arr[i] contains more
        # than one prime factor
        if (factorValue == -1):
            continue
         
        # If arr[i] contains
        # a single prime factor
        else:
            mp[factorValue] = mp.get(factorValue, 0) + 1
 
    # Stores the count of pairs whose
    # product of elements contains only
    # a single distinct prime factor
    res = 0
 
    # Traverse the map mp[]
    for it in mp:
         
        # Stores count of array elements
        # whose prime factor is (it.first)
        X = mp[it]
 
        # Update res
        res += countOf1 * X + (X * (X - 1) ) // 2
 
    return res
 
# Driver Code
if __name__ == '__main__':
     
    arr = [ 1, 2, 3, 4 ]
    N = len(arr)
     
    print(cntsingleFactorPair(arr, N))
 
# This code is contributed by mohit kumar 29




// C# program to implement
// the above approach
using System;
using System.Collections.Generic;
class GFG{
 
// Function to find a single
// distinct prime factor of N
static int singlePrimeFactor(int N)
{
  // Stores distinct
  // prime factors of N
  HashSet<int> disPrimeFact =
          new HashSet<int>();
 
  // Calculate prime factor of N
  for (int i = 2;
           i * i <= N; ++i)
  {
    // Calculate distinct
    // prime factor
    while (N % i == 0)
    {
      // Insert i into
      // disPrimeFact
      disPrimeFact.Add(i);
 
      // Update N
      N /= i;
    }
  }
 
  // If N is not equal to 1
  if(N != 1)
  {
    // Insert N into
    // disPrimeFact
    disPrimeFact.Add(N);
  }
 
  // If N contains a single
  // distinct prime factor
  if (disPrimeFact.Count == 1)
  {
    // Return single distinct
    // prime factor of N
    foreach(int i in disPrimeFact)
      return i;
  }
 
  // If N contains more than
  // one distinct prime factor   
  return -1;
}
 
 
// Function to count pairs in
// the array whose product
// contains only single distinct
// prime factor
static int cntsingleFactorPair(int []arr,
                               int N)
{  
  // Stores count of 1s
  // in the array
  int countOf1 = 0;
 
  // mp[i]: Stores count of array
  // elements whose distinct prime
  // factor is only i
  Dictionary<int,
             int> mp =
             new Dictionary<int,
                            int>();
 
  // Traverse the array arr[]
  for (int i = 0; i < N; i++)
  {
    // If current element is 1
    if(arr[i] == 1)
    {
      countOf1++;
      continue;
    }
 
    // Store distinct
    // prime factor of arr[i]
    int factorValue =
        singlePrimeFactor(arr[i]);
 
    // If arr[i] contains more
    // than one prime factor
    if (factorValue == -1)
    {
      continue;
    }
 
    // If arr[i] contains
    // a single prime factor
    else
    {
      if(mp.ContainsKey(factorValue))
        mp[factorValue] = mp[factorValue] + 1;
      else
        mp.Add(factorValue, 1);
    }
  }
 
  // Stores the count of pairs whose
  // product of elements contains only
  // a single distinct prime factor
  int res = 0;
 
  // Traverse the map mp[]
  foreach(KeyValuePair<int,
                       int> ele1 in mp)
  {
    // Stores count of array
    // elements whose prime
    // factor is (it.first)
    int X = ele1.Value;
 
    // Update res
    res += countOf1 * X +
           (X * (X - 1) ) / 2;
  }
 
  return res;
}
 
// Driver Code
public static void Main()
{
  int []arr = {1, 2, 3, 4};
  int N = arr.Length;
  Console.WriteLine(
         cntsingleFactorPair(arr, N));
}
}
 
// This code is contributed by bgangwar59




<script>
 
// JavaScript program to implement
// the above approach
 
// Function to find a single
// distinct prime factor of N
function singlePrimeFactor(N)
{
     
    // Stores distinct
    // prime factors of N
    var disPrimeFact = {};
     
    // Calculate prime factor of N
    for(var i = 2; i * i <= N; ++i)
    {
         
        // Calculate distinct
        // prime factor
        while (N % i === 0)
        {
             
            // Insert i into
            // disPrimeFact
            disPrimeFact[i] = 1;
             
            // Update N
            N = parseInt(N / i);
        }
    }
     
    // If N is not equal to 1
    if (N !== 1)
    {
         
        // Insert N into
        // disPrimeFact
        disPrimeFact[N] = 1;
    }
     
    // If N contains a single
    // distinct prime factor
    if (Object.keys(disPrimeFact).length === 1)
    {
         
        // Return single distinct
        // prime factor of N
        for(const [key, value] of Object.entries(
            disPrimeFact))
        {
            return key;
        }
    }
     
    // If N contains more than
    // one distinct prime factor
    return -1;
}
 
// Function to count pairs in
// the array whose product
// contains only single distinct
// prime factor
function cntsingleFactorPair(arr, N)
{
     
    // Stores count of 1s
    // in the array
    var countOf1 = 0;
     
    // mp[i]: Stores count of array
    // elements whose distinct prime
    // factor is only i
    var mp = {};
     
    // Traverse the array arr[]
    for(var i = 0; i < N; i++)
    {
         
        // If current element is 1
        if (arr[i] === 1)
        {
            countOf1++;
            continue;
        }
         
        // Store distinct
        // prime factor of arr[i]
        var factorValue = singlePrimeFactor(arr[i]);
         
        // If arr[i] contains more
        // than one prime factor
        if (factorValue === -1)
        {
            continue;
        }
     
        // If arr[i] contains
        // a single prime factor
        else
        {
            if (mp.hasOwnProperty(factorValue))
                mp[factorValue] = mp[factorValue] + 1;
            else
                mp[factorValue] = 1;
        }
    }
     
    // Stores the count of pairs whose
    // product of elements contains only
    // a single distinct prime factor
    var res = 0;
     
    // Traverse the map mp[]
    for(const [key, value] of Object.entries(mp))
    {
         
        // Stores count of array
        // elements whose prime
        // factor is (it.first)
        var X = value;
         
        // Update res
        res = parseInt(res + countOf1 * X +
                        (X * (X - 1)) / 2);
    }
    return res;
}
 
// Driver Code
var arr = [ 1, 2, 3, 4 ];
var N = arr.length;
 
document.write(cntsingleFactorPair(arr, N));
 
// This code is contributed by rdtank
 
</script>

Output
4






Time Complexity: O(N√X), where X is the maximum element of the given array.
Auxiliary Space: O(N)

Using Brute Force:

Approach:

We can use a nested loop to iterate over all possible pairs of elements in the array and check if their product has a single distinct prime factor. We can use a helper function to determine if a number has a single distinct prime factor. 




#include <iostream>
#include <unordered_set>
#include <cmath>
#include <vector>
 
using namespace std;
 
bool has_single_distinct_prime_factor(int n) {
    unordered_set<int> prime_factors;
    while (n % 2 == 0) {
        prime_factors.insert(2);
        n /= 2;
    }
    for (int i = 3; i <= sqrt(n); i += 2) {
        while (n % i == 0) {
            prime_factors.insert(i);
            n /= i;
        }
    }
    if (n > 2) {
        prime_factors.insert(n);
    }
    return prime_factors.size() == 1;
}
 
int count_pairs(vector<int>& arr) {
    int n = arr.size();
    int count = 0;
    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {
            if (has_single_distinct_prime_factor(arr[i] * arr[j])) {
                count++;
            }
        }
    }
    return count;
}
 
int main() {
    vector<int> arr1 = {1, 2, 3, 4};
    vector<int> arr2 = {2, 4, 6, 8};
 
    cout << count_pairs(arr1) << endl; // Output: 4
    cout << count_pairs(arr2) << endl; // Output: 3
 
    return 0;
}




import java.util.HashSet;
import java.util.Set;
import java.util.Vector;
 
public class SingleDistinctPrimeFactor {
    // Function to check if a number has a single distinct prime factor
    static boolean hasSingleDistinctPrimeFactor(int n) {
        Set<Integer> primeFactors = new HashSet<>();
         
        // Handle the case of 2 as a prime factor
        while (n % 2 == 0) {
            primeFactors.add(2);
            n /= 2;
        }
         
        // Check for odd prime factors
        for (int i = 3; i <= Math.sqrt(n); i += 2) {
            while (n % i == 0) {
                primeFactors.add(i);
                n /= i;
            }
        }
         
        // If n is still greater than 2, it is also a prime factor
        if (n > 2) {
            primeFactors.add(n);
        }
         
        // Check if there's only one distinct prime factor
        return primeFactors.size() == 1;
    }
 
    // Function to count pairs with a single distinct prime factor
    static int countPairs(Vector<Integer> arr) {
        int n = arr.size();
        int count = 0;
 
        // Iterate over all pairs of elements in the array
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                if (hasSingleDistinctPrimeFactor(arr.get(i) * arr.get(j))) {
                    count++;
                }
            }
        }
        return count;
    }
 
    public static void main(String[] args) {
        Vector<Integer> arr1 = new Vector<>(java.util.Arrays.asList(1, 2, 3, 4));
        Vector<Integer> arr2 = new Vector<>(java.util.Arrays.asList(2, 4, 6, 8));
 
        // Calculate and print the count of pairs with a single distinct prime factor
        System.out.println(countPairs(arr1)); // Output: 4
        System.out.println(countPairs(arr2)); // Output: 3
    }
}




def has_single_distinct_prime_factor(n):
    prime_factors = set()
    while n % 2 == 0:
        prime_factors.add(2)
        n //= 2
    for i in range(3, int(n**0.5) + 1, 2):
        while n % i == 0:
            prime_factors.add(i)
            n //= i
    if n > 2:
        prime_factors.add(n)
    return len(prime_factors) == 1
 
def count_pairs(arr):
    n = len(arr)
    count = 0
    for i in range(n):
        for j in range(i+1, n):
            if has_single_distinct_prime_factor(arr[i] * arr[j]):
                count += 1
    return count
 
# Example usage
arr1 = [1, 2, 3, 4]
arr2 = [2, 4, 6, 8]
 
print(count_pairs(arr1)) # Output: 4
print(count_pairs(arr2)) # Output: 3




using System;
using System.Collections.Generic;
 
class GFG {
    static bool HasSingleDistinctPrimeFactor(int n)
    {
        HashSet<int> primeFactors = new HashSet<int>();
        while (n % 2 == 0) {
            primeFactors.Add(2);
            n /= 2;
        }
        for (int i = 3; i <= Math.Sqrt(n); i += 2) {
            while (n % i == 0) {
                primeFactors.Add(i);
                n /= i;
            }
        }
        if (n > 2) {
            primeFactors.Add(n);
        }
        return primeFactors.Count == 1;
    }
 
    static int CountPairs(List<int> arr)
    {
        int n = arr.Count;
        int count = 0;
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                if (HasSingleDistinctPrimeFactor(
                        arr[i] * arr[j])) {
                    count++;
                }
            }
        }
        return count;
    }
 
    static void Main()
    {
        List<int> arr1 = new List<int>{ 1, 2, 3, 4 };
        List<int> arr2 = new List<int>{ 2, 4, 6, 8 };
 
        Console.WriteLine(CountPairs(arr1));
        Console.WriteLine(CountPairs(arr2));
    }
}




function hasSingleDistinctPrimeFactor(n) {
    let primeFactors = new Set();
     
    // Divide n by 2 until it's not divisible by 2
    while (n % 2 === 0) {
        primeFactors.add(2);
        n /= 2;
    }
     
    // Check for prime factors starting from 3
    for (let i = 3; i <= Math.sqrt(n); i += 2) {
        while (n % i === 0) {
            primeFactors.add(i);
            n /= i;
        }
    }
     
    // If n is greater than 2, it's a prime factor itself
    if (n > 2) {
        primeFactors.add(n);
    }
     
    // Check if there is exactly one distinct prime factor
    return primeFactors.size === 1;
}
 
function countPairs(arr) {
    let n = arr.length;
    let count = 0;
 
    // Iterate through all pairs of elements in the array
    for (let i = 0; i < n; i++) {
        for (let j = i + 1; j < n; j++) {
            // Check if the product of two elements has a single distinct prime factor
            if (hasSingleDistinctPrimeFactor(arr[i] * arr[j])) {
                count++;
            }
        }
    }
 
    return count;
}
 
// Test cases
let arr1 = [1, 2, 3, 4];
let arr2 = [2, 4, 6, 8];
 
console.log(countPairs(arr1)); // Output: 2
console.log(countPairs(arr2)); // Output: 5

Output
4
3






The time complexity of has_single_distinct_prime_factor(n) function is O(sqrt(n)), as it iterates over all odd integers up to the square root of n, checking if they divide n.

The time complexity of count_pairs(arr) function is O(n^2) since it has two nested loops that iterate over all pairs of elements in the input array arr.

Overall Time complexity; O(n^2)
Overall auxiliary space: O(n)


Article Tags :