Open In App

Counting Good Subarrays in an Array with Distinct Prefix GCDs

Last Updated : 13 Dec, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

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++




// C++ code for the above approach:
#include <bits/stdc++.h>
#include <iostream>
using namespace std;
 
// Function to count number of subarrays
// with distinct GCD
long long solve(int N, vector<int>& A)
{
 
    int i = 0;
    int count = 0;
 
    // Iterate in arary
    while (i < N) {
        int j = i;
 
        // Initialize a map
        map<int, int> m;
        int gc = 0;
        while (j < N) {
            gc = __gcd(A[j], gc);
 
            // If gcd is present in map
            if (m.find(gc) != m.end()) {
                break;
            }
 
            m[gc] = 1;
 
            // Increment in count
            count++;
            j++;
        }
        i++;
    }
 
    // Return the number of subarrays
    return count;
}
 
// Driver code
int main()
{
 
    int N = 4;
    vector<int> A = { 18, 6, 24, 1 };
 
    // Function call
    cout << solve(N, A);
    return 0;
}


Java




import java.util.HashMap;
import java.util.Map;
 
public class Main {
 
    // Function to count the number of subarrays with distinct GCD
    public static long solve(int N, int[] A) {
        int count = 0;
 
        for (int i = 0; i < N; i++) {
            int j = i;
          //Initialize a map
            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;
    }
 
    // Helper function to calculate the GCD of two numbers
    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};
 
        // Function call
        System.out.println(solve(N, A));
    }
}


Python3




from math import gcd
 
# Function to count number of subarrays
# with distinct GCD
def solve(N, A):
    i = 0
    count = 0
 
    # Iterate in array
    while i < N:
        j = i
 
        # Initialize a set
        s = set()
        gc = 0
        while j < N:
            gc = gcd(A[j], gc)
 
            # If gcd is present in set
            if gc in s:
                break
 
            s.add(gc)
 
            # Increment in count
            count += 1
            j += 1
 
        i += 1
 
    # Return the number of subarrays
    return count
 
# Driver code
if __name__ == "__main__":
    N = 4
    A = [18, 6, 24, 1]
 
    # Function call
    print(solve(N, A))
 
# This code is contributed by akshitaguprzj3


C#




// C# code to implement the above approach
 
using System;
using System.Collections.Generic;
 
public class GFG {
 
    // Function to find GCD
    static int GCD(int a, int b)
    {
        while (b != 0) {
            int temp = b;
            b = a % b;
            a = temp;
        }
        return a;
    }
 
    // Function to count number of subarrays with distinct
    // GCD
    static long solve(int N, List<int> A)
    {
        int i = 0;
        int count = 0;
 
        // Iterate in array
        while (i < N) {
            int j = i;
 
            // Initialize a dictionary
            Dictionary<int, int> m
                = new Dictionary<int, int>();
            int gc = 0;
            while (j < N) {
                gc = GCD(A[j], gc);
 
                // If gcd is present in dictionary
                if (m.ContainsKey(gc)) {
                    break;
                }
 
                m[gc] = 1;
 
                // Increment in count
                count++;
                j++;
            }
            i++;
        }
 
        // Return the number of subarrays
        return count;
    }
 
    // Driver code
    static void Main()
    {
        int N = 4;
        List<int> A = new List<int>{ 18, 6, 24, 1 };
 
        // Function call
        Console.WriteLine(solve(N, A));
    }
}
 
// This code is contributed by Abhinav Mahajan (abhinav_m22)


Javascript




function solve(N, A) {
    let i = 0;
    let count = 0;
 
    // Iterate through the array
    while (i < N) {
        let j = i;
 
        // Initialize a Map
        const m = new Map();
        let gcd = 0;
 
        while (j < N) {
            gcd = findGCD(A[j], gcd);
 
            // If gcd is present in the Map
            if (m.has(gcd)) {
                break;
            }
 
            m.set(gcd, 1);
 
            // Increment the count
            count++;
            j++;
        }
        i++;
    }
 
    // Return the number of subarrays
    return count;
}
 
// Function to calculate the GCD (Greatest Common Divisor)
function findGCD(a, b) {
    if (b === 0) {
        return a;
    }
    return findGCD(b, a % b);
}
 
// Driver code
const N = 4;
const A = [18, 6, 24, 1];
 
// Function call
console.log(solve(N, A));


Output

6







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



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads