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 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 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);       // 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 Mp = new HashMap();           // 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 Mp = new Dictionary();           // 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



Output

7

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

My Personal Notes arrow_drop_up
Recommended Articles
Page :