Skip to content
Related Articles

Related Articles

Improve Article

Count of distinct GCDs among all the non-empty subsequences of given array

  • Last Updated : 05 Jul, 2021

Given an integer array arr[] of size N, the task is to calculate the total number of distinct Greatest Common Divisors(GCDs) among all the non-empty subsequences of arr[].

Examples:

Input: arr[]={3,4,8} N=3
Output:
4
Explanation:
The different non-empty subsequences possible are {3}, {4}, {8}, {3,4}, {4,8}, {3,8}, {3,4,8} and their corresponding GCDs are 3,4,8,1,4,1,1. 
Thus, the total number of distinct GCDs is 4 (1,3,4,8).

Input: arr[]={3,11,14,6,12}, N=5
Output:
7

Naive Approach: The naive approach is to find all subsequences, calculate the GCDs for each of them, and finally, calculating the total number of distinct GCDs.



Time Complexity: O(2N.Log(M)), where M is the largest element in the array.

Approach: The given problem can be solved based on the following observations:

  1. The largest possible GCD cannot exceed the largest element of the array(say M). Therefore, all possible GCDs lie between 1 to M.
  2. By iterating over all possible values of GCD i.e from 1 to M, and checking whether there are any multiples of i which are present in the array and have a GCD equal to i, the problem can be solved.

Follow the steps below to solve the problem:

  1. Initialize a variable ans to 0.
  2. Calculate and store the maximum element in arr in a variable, say M.
  3. Store all the elements of arr in a map Mp for constant-time access.
  4. Iterate through all possible values of GCD i.e from 1 to M, using the variable i, and do the following:
    • Iterate through the multiples of M present in arr, using the variable j, and do the following:
    • If the GCD becomes i at any point, increment ans and break.

Below is the implementation of the above approach:

C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to calculate the number
// of distinct GCDs among all
// non-empty subsequences of an array
int distinctGCDs(int arr[], int N)
{
    // variables to store the largest element
// in array and the required count
    int M = -1, ans = 0;
 
    // Map to store whether
// a number is present in A
    map<int, int> Mp;
 
    // calculate largest number
// in A and mapping A to Mp
    for (int i = 0; i < N; i++) {
        M = max(M, arr[i]);
        Mp[arr[i]] = 1;
    }
 
    // iterate over all possible values of GCD
    for (int i = 1; i <= M; i++) {
 
        // variable to check current GCD
        int currGcd = 0;
 
        // iterate over all multiples of i
        for (int j = i; j <= M; j += i) {
 
            // If j is present in A
            if (Mp[j]) {
 
                // calculate gcd of all encountered
                // multiples of i
                currGcd = __gcd(currGcd, j);
 
                // current GCD is possible
                if (currGcd == i) {
                    ans++;
                    break;
                }
            }
        }
    }
    // return answer
    return ans;
}
// Driver code
int main()
{
    // Input
    int arr[] = { 3, 11, 14, 6, 12 };
    int N = sizeof(arr) / sizeof(arr[0]);
 
    // Function calling
    cout << distinctGCDs(arr, N) << endl;
 
    return 0;
}

Java




// Java program for the above approach
import java.util.*;
 
class GFG{
 
static int gcd(int a, int b)
{
    return b == 0 ? a : gcd(b, a % b);
}
 
// Function to calculate the number
// of distinct GCDs among all
// non-empty subsequences of an array
static int distinctGCDs(int []arr, int N)
{
     
    // Variables to store the largest element
    // in array and the required count
    int M = -1, ans = 0;
     
    // Map to store whether
    // a number is present in A
    HashMap<Integer,
               Integer> Mp = new HashMap<Integer,
                                        Integer>();
     
    // Calculate largest number
    // in A and mapping A to Mp
    for(int i = 0; i < N; i++)
    {
        M = Math.max(M, arr[i]);
         
        if (Mp.containsKey(arr[i]))
            Mp.put(arr[i],1);
        else
            Mp.put(arr[i],0);
    }
     
    // Iterate over all possible values of GCD
    for(int i = 1; i <= M; i++)
    {
     
        // Variable to check current GCD
        int currGcd = 0;
         
        // Iterate over all multiples of i
        for(int j = i; j <= M; j += i)
        {
         
            // If j is present in A
            if (Mp.containsKey(j))
            {
             
                // Calculate gcd of all encountered
                // multiples of i
                currGcd = gcd(currGcd, j);
                 
                // Current GCD is possible
                if (currGcd == i)
                {
                    ans++;
                    break;
                }
            }
        }
    }
     
    // Return answer
    return ans;
}
 
// Driver code
public static void main(String [] args)
{
     
    // Input
    int []arr = { 3, 11, 14, 6, 12 };
    int N = arr.length;
 
    // Function calling
    System.out.println(distinctGCDs(arr, N));
}
}
 
// This code is contributed by ukasp.

Python3




# Python 3 program for the above approach
from math import gcd
 
# Function to calculate the number
# of distinct GCDs among all
# non-empty subsequences of an array
def distinctGCDs(arr, N):
   
    # variables to store the largest element
    # in array and the required count
    M = -1
    ans = 0
 
    # Map to store whether
    # a number is present in A
    Mp = {}
 
    # calculate largest number
    # in A and mapping A to Mp
    for i in range(N):
        M = max(M, arr[i])
        Mp[arr[i]] = 1
 
    # iterate over all possible values of GCD
    for i in range(1, M + 1, 1):
       
        # variable to check current GCD
        currGcd = 0
 
        # iterate over all multiples of i
        for j in range(i, M + 1, i):
           
            # If j is present in A
            if (j in Mp):
               
                # calculate gcd of all encountered
                # multiples of i
                currGcd = gcd(currGcd, j)
 
                # current GCD is possible
                if (currGcd == i):
                    ans += 1
                    break
 
    # return answer
    return ans
 
# Driver code
if __name__ == '__main__':
    # Input
    arr = [3, 11, 14, 6, 12]
    N = len(arr)
 
    # Function calling
    print(distinctGCDs(arr, N))
     
    # This code is contributed by bgangwar59.

C#




// C# program for the above approach
using System;
using System.Collections.Generic;
 
class GFG{
 
static int gcd(int a, int b)
{
    return b == 0 ? a : gcd(b, a % b);
}
 
// Function to calculate the number
// of distinct GCDs among all
// non-empty subsequences of an array
static int distinctGCDs(int []arr, int N)
{
     
    // Variables to store the largest element
    // in array and the required count
    int M = -1, ans = 0;
     
    // Map to store whether
    // a number is present in A
    Dictionary<int,
               int> Mp = new Dictionary<int,
                                        int>();
     
    // Calculate largest number
    // in A and mapping A to Mp
    for(int i = 0; i < N; i++)
    {
        M = Math.Max(M, arr[i]);
         
        if (Mp.ContainsKey(arr[i]))
            Mp[arr[i]] = 1;
        else
            Mp.Add(arr[i],1);
    }
     
    // Iterate over all possible values of GCD
    for(int i = 1; i <= M; i++)
    {
     
        // Variable to check current GCD
        int currGcd = 0;
         
        // Iterate over all multiples of i
        for(int j = i; j <= M; j += i)
        {
         
            // If j is present in A
            if (Mp.ContainsKey(j))
            {
             
                // Calculate gcd of all encountered
                // multiples of i
                currGcd = gcd(currGcd, j);
                 
                // Current GCD is possible
                if (currGcd == i)
                {
                    ans++;
                    break;
                }
            }
        }
    }
     
    // Return answer
    return ans;
}
 
// Driver code
public static void Main()
{
     
    // Input
    int []arr = { 3, 11, 14, 6, 12 };
    int N = arr.Length;
 
    // Function calling
    Console.Write(distinctGCDs(arr, N));
}
}
 
// This code is contributed by ipg2016107

Javascript




<script>
        // JavaScript program for the above approach
 
        // Function to calculate gcd
        function gcd(a, b)
        {
            if (b == 0)
                return a;
            return gcd(b, a % b);
        }
 
        // Function to calculate the number
        // of distinct GCDs among all
        // non-empty subsequences of an array
        function distinctGCDs(arr, N)
        {
         
            // variables to store the largest element
            // in array and the required count
            let M = -1, ans = 0;
 
            // Map to store whether
            // a number is present in A
            var Mp = new Map();
 
            // calculate largest number
            // in A and mapping A to Mp
            for (let i = 0; i < N; i++) {
                M = Math.max(M, arr[i]);
                Mp.set(arr[i], 1);
            }
 
            // iterate over all possible values of GCD
            for (let i = 1; i <= M; i++) {
 
                // variable to check current GCD
                let currGcd = 0;
 
                // iterate over all multiples of i
                for (let j = i; j <= M; j += i) {
 
                    // If j is present in A
                    if (Mp.has(j)) {
 
                        // calculate gcd of all encountered
                        // multiples of i
                        currGcd = gcd(currGcd, j);
 
                        // current GCD is possible
                        if (currGcd == i) {
                            ans++;
                            break;
                        }
                    }
                }
            }
            // return answer
            return ans;
        }
        // Driver code
 
        // Input
        let arr = [3, 11, 14, 6, 12];
        let N = arr.length;
 
        // Function calling
        document.write(distinctGCDs(arr, N) + '<br>');
         
  // This code is contributed by Potta Lokesh
    </script>
Output
7

Time Complexity: O(M*log(M)), where M is the largest element in the array
Auxiliary Space: O(M)

 

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.




My Personal Notes arrow_drop_up
Recommended Articles
Page :