Count of pairs in an array whose product is a perfect square

Given an array arr[] of N integers, the task is to find the number of pairs (arr[i], arr[j]) such that arr[i]*arr[j] is a perfect square.

Examples:

Input: arr[] = { 1, 2, 4, 8, 5, 6}
Output: 2
Explanation:
The pairs such that product of element is perfect square are (1, 4) and (8, 2).



Input: arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }
Output: 4
Explanation:
The pairs such that product of element is perfect square are (1, 4), (1, 9), (2, 8) and (4, 9).

Naive Approach:
Run two loop from 1 to n and count all the pairs (i, j) where arr[i]*arr[j] is a perfect square. The time complexity of this approach will be O(N2).

Efficient Approach:
Each integers in arr[] can be represented in following form:

arr[i] = k*x          ..............(1)
where k is not divisible by any perfect square other than 1,
and x = perfect square,

Steps:

  1. Represent every element in form of equation(1).
  2. Then, for every pair (arr[i], arr[j]) in arr[] can be represented as:
    arr[i] = ki*x;
    arr[j] = kj*y;
    where x and y are perfect square
    

    For pairs (arr[i], arr[j]), product of arr[i] and arr[j] can be perfect square if and only if ki = kj

  3. Use Sieve of Eratosthenes to pre compute the value of k for every element in array arr[].
  4. Store the frequency of k for every element in arr[] in map.
  5. Therefore, the total number of pair is given by number of pair formed by element with frequency greater than 1.
  6. The total number of pairs form by n elements is given by:
    Number of Pairs = (f*(f-1))/2
    where f is the frequency of an element.
    

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to calculate the number of
// pairs with product is perfect square
#include <bits/stdc++.h>
using namespace std;
  
// Prime[] array to calculate Prime Number
int prime[100001] = { 0 };
  
// Array k[] to store the value of k for
// each element in arr[]
int k[100001] = { 0 };
  
// For value of k, Seive function is
// implemented
void Seive()
{
    // Initialize k[i] to i
    for (int i = 1; i < 100001; i++)
        k[i] = i;
  
    // Prime Sieve
    for (int i = 2; i < 100001; i++) {
  
        // If i is prime then remove all
        // factors of prime from it
        if (prime[i] == 0)
            for (int j = i; j < 100001; j += i) {
  
                // Update that j is not
                // prime
                prime[j] = 1;
  
                // Remove all square divisors
                // i.e. if k[j] is divisible
                // by i*i then divide it by i*i
                while (k[j] % (i * i) == 0)
                    k[j] /= (i * i);
            }
    }
}
  
// Function that return total count
// of pairs with pefect square product
int countPairs(int arr[], int n)
{
    // Map used to store the frequency of k
    unordered_map<int, int> freq;
  
    // Store the frequency of k
    for (int i = 0; i < n; i++) {
        freq[k[arr[i]]]++;
    }
  
    int sum = 0;
  
    // The total number of pairs is the
    // summation of (fi * (fi - 1))/2
    for (auto i : freq) {
        sum += ((i.second - 1) * i.second) / 2;
    }
  
    return sum;
}
  
// Driver code
int main()
{
    int arr[] = { 1, 2, 4, 8, 5, 6 };
  
    // Size of arr[]
    int n = sizeof(arr) / sizeof(int);
  
    // To pre compute the value of k
    Seive();
  
    // Function that return total count
    // of pairs with pefect square product
    cout << countPairs(arr, n) << endl;
  
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to calculate the number of
// pairs with product is perfect square
import java.util.*;
  
class GFG{
   
// Prime[] array to calculate Prime Number
static int []prime = new int[100001];
   
// Array k[] to store the value of k for
// each element in arr[]
static int []k = new int[100001];
   
// For value of k, Seive function is
// implemented
static void Seive()
{
    // Initialize k[i] to i
    for (int i = 1; i < 100001; i++)
        k[i] = i;
   
    // Prime Sieve
    for (int i = 2; i < 100001; i++) {
   
        // If i is prime then remove all
        // factors of prime from it
        if (prime[i] == 0)
            for (int j = i; j < 100001; j += i) {
   
                // Update that j is not
                // prime
                prime[j] = 1;
   
                // Remove all square divisors
                // i.e. if k[j] is divisible
                // by i*i then divide it by i*i
                while (k[j] % (i * i) == 0)
                    k[j] /= (i * i);
            }
    }
}
   
// Function that return total count
// of pairs with pefect square product
static int countPairs(int arr[], int n)
{
    // Map used to store the frequency of k
    HashMap<Integer,Integer> freq = new HashMap<Integer,Integer>();
   
    // Store the frequency of k
    for (int i = 0; i < n; i++) {
        if(freq.containsKey(k[arr[i]])) {
            freq.put(k[arr[i]], freq.get(k[arr[i]])+1);
        }
        else
            freq.put(k[arr[i]], 1);
    }
   
    int sum = 0;
   
    // The total number of pairs is the
    // summation of (fi * (fi - 1))/2
    for (Map.Entry<Integer,Integer> i : freq.entrySet()){
        sum += ((i.getValue() - 1) * i.getValue()) / 2;
    }
   
    return sum;
}
   
// Driver code
public static void main(String[] args)
{
    int arr[] = { 1, 2, 4, 8, 5, 6 };
   
    // Size of arr[]
    int n = arr.length;
   
    // To pre compute the value of k
    Seive();
   
    // Function that return total count
    // of pairs with pefect square product
    System.out.print(countPairs(arr, n) +"\n");
   
}
}
  
// This code is contributed by 29AjayKumar

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program to calculate the number of
// pairs with product is perfect square
using System;
using System.Collections.Generic;
  
class GFG{
    
// Prime[] array to calculate Prime Number
static int []prime = new int[100001];
    
// Array k[] to store the value of k for
// each element in []arr
static int []k = new int[100001];
    
// For value of k, Seive function is
// implemented
static void Seive()
{
    // Initialize k[i] to i
    for (int i = 1; i < 100001; i++)
        k[i] = i;
    
    // Prime Sieve
    for (int i = 2; i < 100001; i++) {
    
        // If i is prime then remove all
        // factors of prime from it
        if (prime[i] == 0)
            for (int j = i; j < 100001; j += i) {
    
                // Update that j is not
                // prime
                prime[j] = 1;
    
                // Remove all square divisors
                // i.e. if k[j] is divisible
                // by i*i then divide it by i*i
                while (k[j] % (i * i) == 0)
                    k[j] /= (i * i);
            }
    }
}
    
// Function that return total count
// of pairs with pefect square product
static int countPairs(int []arr, int n)
{
    // Map used to store the frequency of k
    Dictionary<int,int> freq = new Dictionary<int,int>();
    
    // Store the frequency of k
    for (int i = 0; i < n; i++) {
        if(freq.ContainsKey(k[arr[i]])) {
            freq[k[arr[i]]] = freq[k[arr[i]]]+1;
        }
        else
            freq.Add(k[arr[i]], 1);
    }
    
    int sum = 0;
    
    // The total number of pairs is the
    // summation of (fi * (fi - 1))/2
    foreach (KeyValuePair<int,int> i in freq){
        sum += ((i.Value - 1) * i.Value) / 2;
    }
    
    return sum;
}
    
// Driver code
public static void Main(String[] args)
{
    int []arr = { 1, 2, 4, 8, 5, 6 };
    
    // Size of []arr
    int n = arr.Length;
    
    // To pre compute the value of k
    Seive();
    
    // Function that return total count
    // of pairs with pefect square product
    Console.Write(countPairs(arr, n) +"\n");  
}
}
  
// This code is contributed by PrinciRaj1992

chevron_right


Output:

2

Time Complexity: O(N*log(log N))

GeeksforGeeks has prepared a complete interview preparation course with premium videos, theory, practice problems, TA support and many more features. Please refer Placement 100 for details




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : 29AjayKumar, princiraj1992