Open In App

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

Last Updated : 05 Jul, 2021
Improve
Improve
Like Article
Like
Save
Share
Report

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)

 



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

Similar Reads