Open In App

Count of elements which is product of a pair or an element square

Last Updated : 10 May, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

Given an array arr[] of N positive integers, the task is to count the number of array elements which can be expressed as the product of two distinct array elements or as a square of any array element.

Examples: 

Input: N = 5, arr[] = {3, 2, 6, 18, 4} 
Output:
Explanation: 
3 elements from the given array 6, 18 and 4 can be expressed as {2 * 3, 6 * 3, 2 * 2} respectively.

Input: N = 6, arr[] = {5, 15, 3, 7, 10, 17} 
Output:
Explanation: 
Only 15 can be expressed as 5 * 3. 

Naive Approach: 
The simplest approach is to traverse the array in the range [0, N-1] and for each number having index value i within the given range, run a nested loop over the same array to find out the two values whose product is arr[i]. If a pair of numbers is found, print 1 else print 0 against the corresponding index. 

Time Complexity: O(N3)

Efficient Approach: 
To solve the problem, we need to find all factors of each element and for every element, check if any pair of factors of that element is present in the array or not. Follow the steps below to solve the problem:  

  1. Sort the given array in increasing order.
  2. Now, traverse the array and for each element, find all pairs of factors of that element and check if any of the pairs exist in the array or not using Binary Search.
  3. Sorting the array allows us to perform Binary Search while searching for factors, thus, reducing the computational complexity to O(logN).
  4. If any such pair is found, increase the count and move to the next element and repeat the same process.
  5. Print the final count of all such numbers in the array.

Below is the implementation of the above approach:  

C++




// C++ Program to implement the
// above approach
#include <bits/stdc++.h>
using namespace std;
 
// Stores all factors a number
vector<int> v[100000];
 
// Function to calculate and
// store in a vector
void div(int n)
{
    for (int i = 2; i <= sqrt(n);
         i++) {
 
        if (n % i == 0) {
            v[n].push_back(i);
        }
    }
}
 
// Function to return the count of
// array elements which are a
// product of two array elements
int prodof2elements(int arr[], int n)
{
    int arr2[n];
 
    // Copy elements into a
    // a duplicate array
    for (int i = 0; i < n; i++) {
        arr2[i] = arr[i];
    }
 
    // Sort the duplicate array
    sort(arr2, arr2 + n);
 
    // Store the count of elements
    int ans = 0;
 
    for (int i = 0; i < n; i++) {
 
        // If the factors are not
        // calculated already
        if (v[arr[i]].size() == 0)
            div(arr[i]);
 
        // Traverse its factors
        for (auto j : v[arr[i]]) {
 
            // If a pair of
            // factors is found
            if (binary_search(
                    arr2, arr2 + n, j)
                and binary_search(
                        arr2, arr2 + n,
                        arr[i] / j)) {
                ans++;
                break;
            }
        }
    }
 
    return ans;
}
 
// Driver Code
int main()
{
    int arr[] = { 2, 1, 8, 4, 32, 18 };
 
    int N = sizeof(arr) / sizeof(arr[0]);
 
    cout << prodof2elements(arr, N);
 
    return 0;
}


Java




// Java Program to implement the
// above approach
import java.util.*;
class GFG{
 
// Stores all factors a number
static Vector<Integer>[] v =
       new Vector[100000];
 
// Function to calculate and
// store in a vector
static void div(int n)
{
  for (int i = 2;
           i <= Math.sqrt(n); i++)
  {
    if (n % i == 0)
    {
      v[n].add(i);
    }
  }
}
 
// Function to return the count of
// array elements which are a
// product of two array elements
static int prodof2elements(int arr[],
                           int n)
{
  int []arr2 = new int[n];
 
  // Copy elements into a
  // a duplicate array
  for (int i = 0; i < n; i++)
  {
    arr2[i] = arr[i];
  }
 
  // Sort the duplicate
  // array
  Arrays.sort(arr2);
 
  // Store the count
  // of elements
  int ans = 0;
 
  for (int i = 0; i < n; i++)
  {
    // If the factors are not
    // calculated already
    if (v[arr[i]].size() == 0)
      div(arr[i]);
 
    // Traverse its factors
    for (int j : v[arr[i]])
    {
      // If a pair of
      // factors is found
      if (Arrays.binarySearch(arr2, j) >= 0 &&
          Arrays.binarySearch(arr2,
          (int)arr[i] / j) >= 0)
      {
        ans++;
        break;
      }
    }
  }
 
  return ans;
}
 
// Driver Code
public static void main(String[] args)
{
  int arr[] = {2, 1, 8, 4, 32, 18};
  int N = arr.length;
   
  for (int i = 0; i < v.length; i++)
    v[i] = new Vector<Integer>();
 
  System.out.print(prodof2elements(arr, N));
}
}
 
// This code is contributed by Princi Singh


Python3




# Python3 program to implement the
# above approach
import math
 
# Stores all factors a number
v = [[] for i in range(100000)]
 
# Function to calculate and
# store in a vector
def div(n):
     
    global v
     
    for i in range(2, int(math.sqrt(n)) + 1):
        if (n % i == 0):
            v[n].append(i)
 
# Function to return the count of
# array elements which are a
# product of two array elements
def prodof2elements(arr, n):
 
    # Copy elements into a
    # a duplicate array
    arr2 = arr.copy()
 
    # Sort the duplicate array
    arr2.sort()
 
    # Store the count of elements
    ans = 0
 
    for i in range(n):
         
        # If the factors are not
        # calculated already
        if (len(v[arr[i]]) == 0):
            div(arr[i])
 
        # Traverse its factors
        for j in v[arr[i]]:
             
            # If a pair of
            # factors is found
            if j in arr2:
                if int(arr[i] / j) in arr2:
                    ans += 1
                    break
 
    return ans
 
# Driver Code
arr = [ 2, 1, 8, 4, 32, 18 ]
N = len(arr)
 
print(prodof2elements(arr, N))
 
# This code is contributed by avanitrachhadiya2155


C#




// C# Program to implement the
// above approach
using System;
using System.Collections.Generic;
class GFG{
 
// Stores all factors a number
static List<int>[] v =
       new List<int>[100000];
 
// Function to calculate and
// store in a vector
static void div(int n)
{
  for (int i = 2;
           i <= Math.Sqrt(n); i++)
  {
    if (n % i == 0)
    {
      v[n].Add(i);
    }
  }
}
 
// Function to return the count of
// array elements which are a
// product of two array elements
static int prodof2elements(int []arr,
                           int n)
{
  int []arr2 = new int[n];
 
  // Copy elements into a
  // a duplicate array
  for (int i = 0; i < n; i++)
  {
    arr2[i] = arr[i];
  }
 
  // Sort the duplicate
  // array
  Array.Sort(arr2);
 
  // Store the count
  // of elements
  int ans = 0;
 
  for (int i = 0; i < n; i++)
  {
    // If the factors are not
    // calculated already
    if (v[arr[i]].Count == 0)
      div(arr[i]);
 
    // Traverse its factors
    foreach (int j in v[arr[i]])
    {
      // If a pair of
      // factors is found
      if (Array.BinarySearch(arr2, j) >= 0 &&
          Array.BinarySearch(arr2,
          (int)arr[i] / j) >= 0)
      {
        ans++;
        break;
      }
    }
  }
 
  return ans;
}
 
// Driver Code
public static void Main(String[] args)
{
  int []arr = {2, 1, 8, 4, 32, 18};
  int N = arr.Length;
   
  for (int i = 0; i < v.Length; i++)
    v[i] = new List<int>();
 
  Console.Write(prodof2elements(arr, N));
}
}
 
// This code is contributed by Amit Katiyar


Javascript




<script>
 
// JavaScript implementation of above approach
 
// Stores all factors a number
let v = new Array(100000).fill(0).map(()=>[]);
 
// Function to calculate and
// store in a vector
function div(n)
{
    for (let i = 2; i <= Math.sqrt(n);i++) {
 
        if (n % i == 0) {
            v[n].push(i);
        }
    }
}
 
// Function to return the count of
// array elements which are a
// product of two array elements
function prodof2elements(arr, n)
{
    let arr2 = arr.slice(0,)
 
    // Sort the duplicate array
    arr2.sort((a,b)=>a-b);
 
    // Store the count of elements
    let ans = 0;
 
    for (let i = 0; i < n; i++) {
 
        // If the factors are not
        // calculated already
        if (v[arr[i]].length == 0)
            div(arr[i]);
 
        // Traverse its factors
        for (let j of v[arr[i]]) {
 
            // If a pair of
            // factors is found
            if (arr2.includes(j) && arr2.includes(Math.floor(arr[i]/j))){
                ans++;
                break;
            }
        }
    }
 
    return ans;
}
 
// Driver Code
 
let arr = [ 2, 1, 8, 4, 32, 18 ];
let N = arr.length;
document.write(prodof2elements(arr, N),"</br>");
 
// This code is contributed by shinjanpatra
 
</script>


Output: 

3

 

Time Complexity: O(N3/2*log N) 
Auxiliary Space: O(N)



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads