Given an array arr[] consisting of N positive integers, the task is to count the number of subarrays with product of its elements equal to a perfect cube.
Examples:
Input: arr[] = {1, 8, 4, 2}
Output: 6
Explanation:
The subarrays with product of elements equal to a perfect cube are:
- {1}. Therefore, product of subarray = 1 (= (1)3).
- {1, 8}. Therefore, product of subarray = 8 ( = 23).
- {8}. Therefore, product of subarray = 8 = (23).
- {4, 2}. Therefore, product of subarray = 8 (= 23).
- {8, 4, 2}. Therefore, product of subarray = 64 (= 43).
- {1, 8, 4, 2}. Therefore, product of subarray = 64 (= 43).
Therefore, the total count is 6.
Input: arr[] = {10, 10,10}
Output: 1
Naive Approach: The simplest approach is to generate all possible subarrays from the given array and count those subarrays whose product of subarray elements is a perfect cube. After checking for all the subarrays, print the count obtained.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
bool perfectCube( int N)
{
int cube_root;
cube_root = ( int )round( pow (N, 1.0 / 3.0));
if (cube_root * cube_root * cube_root == N) {
return true ;
}
return false ;
}
void countSubarrays( int a[], int n)
{
int ans = 0;
for ( int i = 0; i < n; i++) {
int prod = 1;
for ( int j = i; j < n; j++) {
prod = prod * a[j];
if (perfectCube(prod))
ans++;
}
}
cout << ans;
}
int main()
{
int arr[] = { 1, 8, 4, 2 };
int N = sizeof (arr) / sizeof (arr[0]);
countSubarrays(arr, N);
return 0;
}
|
Java
import java.util.*;
public class GFG
{
public static void main(String args[])
{
int arr[] = { 1 , 8 , 4 , 2 };
int N = arr.length;
countSubarrays(arr, N);
}
static void countSubarrays( int a[], int n)
{
int ans = 0 ;
for ( int i = 0 ; i < n; i++)
{
int prod = 1 ;
for ( int j = i; j < n; j++)
{
prod = prod * a[j];
if (perfectCube(prod))
ans++;
}
}
System.out.println(ans);
}
static boolean perfectCube( int N)
{
int cube_root;
cube_root = ( int )Math.round(Math.pow(N, 1.0 / 3.0 ));
if (cube_root * cube_root * cube_root == N)
{
return true ;
}
return false ;
}
}
|
Python3
def perfectCube(N):
cube_root = round ( pow (N, 1 / 3 ))
if (cube_root * cube_root * cube_root = = N):
return True
return False
def countSubarrays(a, n):
ans = 0
for i in range (n):
prod = 1
for j in range (i, n):
prod = prod * a[j]
if (perfectCube(prod)):
ans + = 1
print (ans)
if __name__ = = "__main__" :
arr = [ 1 , 8 , 4 , 2 ]
N = len (arr)
countSubarrays(arr, N)
|
C#
using System;
public class GFG
{
public static void Main(String[] args)
{
int [] arr = { 1, 8, 4, 2 };
int N = arr.Length;
countSubarrays(arr, N);
}
static void countSubarrays( int [] a, int n)
{
int ans = 0;
for ( int i = 0; i < n; i++)
{
int prod = 1;
for ( int j = i; j < n; j++)
{
prod = prod * a[j];
if (perfectCube(prod))
ans++;
}
}
Console.Write(ans);
}
static bool perfectCube( int N)
{
int cube_root;
cube_root = ( int )Math.Round(Math.Pow(N, 1.0 / 3.0));
if (cube_root * cube_root * cube_root == N)
{
return true ;
}
return false ;
}
}
|
Javascript
<script>
function countSubarrays(a , n)
{
var ans = 0;
for (i = 0; i < n; i++)
{
var prod = 1;
for (j = i; j < n; j++)
{
prod = prod * a[j];
if (perfectCube(prod))
ans++;
}
}
document.write(ans);
}
function perfectCube(N)
{
var cube_root;
cube_root = parseInt(Math.round(Math.pow(N, 1.0 / 3.0)));
if (cube_root * cube_root * cube_root == N)
{
return true ;
}
return false ;
}
var arr = [ 1, 8, 4, 2 ];
var N = arr.length;
countSubarrays(arr, N);
</script>
|
Time Complexity: O(N2)
Auxiliary Space: O(1)
Efficient Approach: The above approach can also be optimized by storing the number of prime factors modulo 3 in a HashMap while traversing the array and count perfect cubes accordingly. Follow the steps below to solve the problem:
- Initialize a variable, say ans, to store the required result, and an array V with 0s to store the frequency of prime factors mod 3 for every element in the given array arr[].
- Initialize a Hashmap, say M, to store the frequency of the current state of prime factors and increment V by 1 in the HashMap.
- Traverse the array arr[] using the variable i perform the following steps:
- After completing the above steps. print the value of ans as the result.
Below is the implementation of the above approach:
C++14
#include <bits/stdc++.h>
using namespace std;
#define MAX 1e5
void primeFactors(vector< int >& v, int n)
{
for ( int i = 2; i * i <= n; i++) {
while (n % i == 0) {
v[i]++;
v[i] %= 3;
n /= i;
}
}
if (n != 1) {
v[n]++;
v[n] %= 3;
}
}
void countSubarrays( int arr[], int n)
{
int ans = 0;
vector< int > v(MAX, 0);
map<vector< int >, int > mp;
mp[v]++;
for ( int i = 0; i < n; i++) {
primeFactors(v, arr[i]);
ans += mp[v];
mp[v]++;
}
cout << ans;
}
int main()
{
int arr[] = { 1, 8, 4, 2 };
int N = sizeof (arr) / sizeof (arr[0]);
countSubarrays(arr, N);
return 0;
}
|
Java
import java.io.*;
import java.lang.*;
import java.util.*;
class GFG{
static int MAX = ( int )(1e5);
static class Key
{
int arr[];
Key( int arr[])
{
this .arr = arr;
}
@Override public int hashCode()
{
return 31 + Arrays.hashCode(arr);
}
@Override public boolean equals(Object obj)
{
if ( this == obj)
return true ;
if (obj == null ||
(getClass() != obj.getClass()))
return false ;
Key other = (Key)obj;
if (!Arrays.equals(arr, other.arr))
return false ;
return true ;
}
}
static void primeFactors( int v[], int n)
{
for ( int i = 2 ; i * i <= n; i++)
{
while (n % i == 0 )
{
v[i]++;
v[i] %= 3 ;
n /= i;
}
}
if (n != 1 )
{
v[n]++;
v[n] %= 3 ;
}
}
static void countSubarrays( int arr[], int n)
{
int ans = 0 ;
int v[] = new int [MAX];
HashMap<Key, Integer> mp = new HashMap<>();
mp.put( new Key(v), 1 );
for ( int i = 0 ; i < n; i++)
{
primeFactors(v, arr[i]);
ans += mp.getOrDefault( new Key(v), 0 );
Key vv = new Key(v);
mp.put(vv, mp.getOrDefault(vv, 0 ) + 1 );
}
System.out.println(ans);
}
public static void main(String[] args)
{
int arr[] = { 1 , 8 , 4 , 2 };
int N = arr.length;
countSubarrays(arr, N);
}
}
|
Python3
from typing import List
from collections import defaultdict
MAX = ( int )( 1e5 )
class Key:
def __init__( self , arr):
self .arr = arr
def __hash__( self ):
return 31 + hash ( tuple ( self .arr))
def __eq__( self , other):
return self .arr = = other.arr
def primeFactors(v: List [ int ], n: int ):
for i in range ( 2 , int (n * * 0.5 ) + 1 ):
while n % i = = 0 :
v[i] + = 1
v[i] % = 3
n / = i
if n ! = 1 :
v[n] + = 1
v[n] % = 3
def countSubarrays(arr: List [ int ], n: int ):
ans = 0
v = [ 0 ] * MAX
mp = defaultdict( int )
mp[Key(v)] = 1
for i in range (n):
primeFactors(v, arr[i])
ans + = mp[Key(v)]
vv = Key(v)
mp[vv] + = 1
print (ans)
arr = [ 1 , 8 , 4 , 2 ]
N = len (arr)
countSubarrays(arr, N)
|
C#
using System;
using System.Collections.Generic;
using System.Linq;
class GFG
{
static int MAX = ( int )(1e5);
class Key
{
int [] arr;
public Key( int [] arr)
{
this .arr = arr;
}
public override int GetHashCode()
{
return 31 + arr.GetHashCode();
}
public override bool Equals( object obj)
{
if ( this == obj)
return true ;
if (obj == null ||
(GetType() != obj.GetType()))
return false ;
Key other = (Key)obj;
if (!arr.SequenceEqual(other.arr))
return false ;
return true ;
}
}
static void primeFactors( int [] v, int n)
{
for ( int i = 2; i * i <= n; i++)
{
while (n % i == 0)
{
v[i]++;
v[i] %= 3;
n /= i;
}
}
if (n != 1)
{
v[n]++;
v[n] %= 3;
}
}
static void countSubarrays( int [] arr, int n)
{
int ans = 0;
int [] v = new int [MAX];
Dictionary<Key, int > mp = new Dictionary<Key, int >();
mp[ new Key(v)] = 1;
for ( int i = 0; i < n-1; i++)
{
primeFactors(v, arr[i]);
ans += mp.GetValueOrDefault( new Key(v), 0);
Key vv = new Key(v);
mp[vv] = mp.GetValueOrDefault(vv, 0) + 1;
}
Console.WriteLine(ans);
}
public static void Main( string [] args)
{
int [] arr = { 1, 8, 4, 2 };
int N = arr.Length;
countSubarrays(arr, N);
}
}
|
Javascript
function primeFactors(v, n) {
for (let i = 2; i * i <= n; i++) {
while (n % i == 0) {
v[i]++;
v[i] %= 3;
n /= i;
}
}
if (n != 1) {
v[n]++;
v[n] %= 3;
}
}
function countSubarrays(arr, n) {
let ans = 0;
let v = Array(1e5).fill(0);
let mp = new Map();
mp.set(v, 1);
for (let i = 0; i < n; i++) {
primeFactors(v, arr[i]);
ans += mp.get(v)-1;
mp.set(v, mp.get(v) + 1);
}
console.log(ans);
}
let arr = [1, 8, 4, 2];
let N = arr.length;
countSubarrays(arr, N);
|
Time Complexity: O(N3/2)
Auxiliary Space: O(N)
Related Topic: Subarrays, Subsequences, and Subsets in Array