Counting Good Subarrays in an Array with Distinct Prefix GCDs
Last Updated :
13 Dec, 2023
Given an array A[] of size N. Count the number of good subarrays of the given array.
- If the prefix gcd array has only distinct elements in it then the array is said to be good.
- An array pref[] is said to be prefix gcd array of array B[] if pref[i] = gcd(B[0], B[1],.. B[i])
Note: For example, the array {15, 6, 19} is good as the prefix gcd array will be {15, 3, 1} which has every element distinct, and the array {18, 6, 24} is bad as the prefix gcd array will be {18, 6, 6} which doesn’t have every element distinct.
Examples:
Input: N = 4, A[] = {18, 6, 24, 1}
Output: 6
Explanation: all good subarrays are {18}, {6}, {24}, {1}, {18, 6}, {24, 1}
Input: N = 2, A[] = {11, 11}
Output: 2
Explanation: All good subarrays are {11}, {11}
Approach: This can be solved with the following idea:
Using Map data structure, insert values of gcd in map. As, taking prefix of each element in array, if gcd already exist then we need to break. Otherwise, we need to increment count.
Below are the steps involved:
- Initialize a map m.
- Iterate in array i.e. i from 0 to N:
- Iterate in j from i to N:
- gcd = __gcd(A[j], gcd).
- If gcd present in map, break the loop.
- If not insert value in map, increment in count by 1.
- Return the count, i.e. the number of subarrays.
Below is the implementation of the code:
C++
#include <bits/stdc++.h>
#include <iostream>
using namespace std;
long long solve( int N, vector< int >& A)
{
int i = 0;
int count = 0;
while (i < N) {
int j = i;
map< int , int > m;
int gc = 0;
while (j < N) {
gc = __gcd(A[j], gc);
if (m.find(gc) != m.end()) {
break ;
}
m[gc] = 1;
count++;
j++;
}
i++;
}
return count;
}
int main()
{
int N = 4;
vector< int > A = { 18, 6, 24, 1 };
cout << solve(N, A);
return 0;
}
|
Java
import java.util.HashMap;
import java.util.Map;
public class Main {
public static long solve( int N, int [] A) {
int count = 0 ;
for ( int i = 0 ; i < N; i++) {
int j = i;
Map<Integer, Integer> m = new HashMap<>();
int gc = 0 ;
while (j < N) {
gc = gcd(A[j], gc);
if (m.containsKey(gc)) {
break ;
}
m.put(gc, 1 );
count++;
j++;
}
}
return count;
}
public static int gcd( int a, int b) {
if (b == 0 ) {
return a;
}
return gcd(b, a % b);
}
public static void main(String[] args) {
int N = 4 ;
int [] A = { 18 , 6 , 24 , 1 };
System.out.println(solve(N, A));
}
}
|
Python3
from math import gcd
def solve(N, A):
i = 0
count = 0
while i < N:
j = i
s = set ()
gc = 0
while j < N:
gc = gcd(A[j], gc)
if gc in s:
break
s.add(gc)
count + = 1
j + = 1
i + = 1
return count
if __name__ = = "__main__" :
N = 4
A = [ 18 , 6 , 24 , 1 ]
print (solve(N, A))
|
C#
using System;
using System.Collections.Generic;
public class GFG {
static int GCD( int a, int b)
{
while (b != 0) {
int temp = b;
b = a % b;
a = temp;
}
return a;
}
static long solve( int N, List< int > A)
{
int i = 0;
int count = 0;
while (i < N) {
int j = i;
Dictionary< int , int > m
= new Dictionary< int , int >();
int gc = 0;
while (j < N) {
gc = GCD(A[j], gc);
if (m.ContainsKey(gc)) {
break ;
}
m[gc] = 1;
count++;
j++;
}
i++;
}
return count;
}
static void Main()
{
int N = 4;
List< int > A = new List< int >{ 18, 6, 24, 1 };
Console.WriteLine(solve(N, A));
}
}
|
Javascript
function solve(N, A) {
let i = 0;
let count = 0;
while (i < N) {
let j = i;
const m = new Map();
let gcd = 0;
while (j < N) {
gcd = findGCD(A[j], gcd);
if (m.has(gcd)) {
break ;
}
m.set(gcd, 1);
count++;
j++;
}
i++;
}
return count;
}
function findGCD(a, b) {
if (b === 0) {
return a;
}
return findGCD(b, a % b);
}
const N = 4;
const A = [18, 6, 24, 1];
console.log(solve(N, A));
|
Time Complexity: O(N*log N)
Auxiliary Space: O(N)
Share your thoughts in the comments
Please Login to comment...