Skip to content
Related Articles

Related Articles

Improve Article
Save Article
Like Article

Count subsequences with GCD equal to X

  • Last Updated : 05 Oct, 2021

Given an array arr[] consisting of N integers and a positive integer X, the task is to count subsequences with GCD exactly X.

Examples:

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.

Input: arr[] = {6, 4, 30}  X = 2
Output: 3
Explanation: Subsequences with GCD(=2) are { {6, 4, 30}, {4, 30}, {6, 4} }. Hence, 3 is the answer.



Input: arr[] = {6, 6, 6}  X = 3
Output: 0
 

Approach: The given problem can be solved with the help of Dynamic Programming. Follow the steps below to solve the given problem.

  • Define a 2-D dp table dp[i][j] which will denote the number of valid subsequences till index i with GCD(= j).
  • For each iteration we have 2 choices:
    • Take the current element: The dp table can be updated as dp[i + 1][gcd(j, arr[i])] += dp[i][j].
    • Skip the current element: The dp table can be updated as dp[i+1][j] += dp[i][j].
  • The base case is dp[0][0] = 1.
  • Since the gcd of two numbers can never be greater than the two numbers, so the values of j will be up to the maximum element in the array. Therefore,  it can be solved iteratively and the final answer will be dp[N][X].

Below is the implementation of the above approach:

C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to find the total subsequences
// having GCD = X
int totalValidSubsequences(
    vector<int> arr, int X, int N)
{
    // Find the maximum element of
    // the array
    int mx = *max_element(
        arr.begin(), arr.end());
 
    // Check if X is greater than mx
    if (X > mx) {
        return 0;
    }
    // Make a 2-d dp table of
    // size [n+1, mx + 1]
    vector<vector<int> > dp(
        N + 1, vector<int>(mx + 1, 0));
 
    // Base Case
    dp[0][0] = 1;
 
    for (int i = 0; i < N; i++) {
 
        // Iterate through all possible
        // indexes
        for (int j = 0; j <= mx; j++) {
 
            // Iterate through all
            // possible values
 
            // Case 1. Skip the element
            dp[i + 1][j] += dp[i][j];
 
            // Case 2. Skip the current element
            dp[i + 1][__gcd(j, arr[i])] += dp[i][j];
        }
    }
 
    // Return the answer dp[N][X]
    return dp[N][X];
}
 
// Driver Code
int main()
{
    vector<int> arr = { 6, 4, 30 };
    int X = 2;
    int N = arr.size();
    cout << totalValidSubsequences(arr, X, N);
 
    return 0;
}

Java




// Java program for the above approach
 
import java.io.*;
import java.util.Arrays;
import java.util.Collections;
 
class GFG {
       
       // Function to find maximum in arr[]
     static int max(int[] arr)
     {
            
         // Initialize maximum element
         int max = arr[0];
         
         // Traverse array elements from second and
         // compare every element with current max 
         for (int i = 1; i < arr.length; i++)
             if (arr[i] > max)
                 max = arr[i];
         
         return max;
     }
   
      // Recursive function to return gcd of a and b
      static int gcd(int a, int b)
    {
      if (b == 0)
        return a;
      return gcd(b, a % b);
    }
 
    // Function to find the total subsequences
    // having GCD = X
    static int totalValidSubsequences(int[] arr,
                                      int X, int N)
    {
        // Find the maximum element of
        // the array
        int mx = max(arr);
 
        // Check if X is greater than mx
        if (X > mx) {
            return 0;
        }
        // Make a 2-d dp table of
        // size [n+1, mx + 1]
        int dp[][] = new int[N + 1][mx + 1];
 
        // Base Case
        dp[0][0] = 1;
 
        for (int i = 0; i < N; i++) {
 
            // Iterate through all possible
            // indexes
            for (int j = 0; j <= mx; j++) {
 
                // Iterate through all
                // possible values
 
                // Case 1. Skip the element
                dp[i + 1][j] += dp[i][j];
 
                // Case 2. Skip the current element
                dp[i + 1][gcd(j, arr[i])] += dp[i][j];
            }
        }
 
        // Return the answer dp[N][X]
        return dp[N][X];
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        int arr[] = { 6, 4, 30 };
           int X = 2;
        int N = arr.length;
           System.out.println(totalValidSubsequences(arr, X, N));
    }
}
 
// This code is contributed by Dharanendra L V.

Python3




# Python 3 program for the above approach
from math import gcd
 
# Function to find the total subsequences
# having GCD = X
def totalValidSubsequences(arr, X, N):
   
    # Find the maximum element of
    # the array
    mx = max(arr)
 
    # Check if X is greater than mx
    if (X > mx):
        return 0
    # Make a 2-d dp table of
    # size [n+1, mx + 1]
    dp = [[0 for i in range(mx+1)] for j in range(N + 1)]
 
    # Base Case
    dp[0][0] = 1
 
    for i in range(N):
       
        # Iterate through all possible
        # indexes
        for j in range(mx+1):
           
            # Iterate through all
            # possible values
 
            # Case 1. Skip the element
            dp[i + 1][j] += dp[i][j]
 
            # Case 2. Skip the current element
            dp[i + 1][gcd(j, arr[i])] += dp[i][j]
 
    # Return the answer dp[N][X]
    return dp[N][X]
 
# Driver Code
if __name__ == '__main__':
    arr = [6, 4, 30]
    X = 2
    N = len(arr)
    print(totalValidSubsequences(arr, X, N))
     
    # This code is contributed by SURENDRA_GANGWAR.

C#




// C# program for the above approach
using System;
using System.Collections.Generic;
 
class GFG{
 
       // Function to find maximum in arr[]
static int max(int []arr)
{
   
  // Initialize maximum element
  int max = arr[0];
   
  // Traverse array elements from second and
  // compare every element with current max 
  for (int i = 1; i < arr.Length; i++)
             if (arr[i] > max)
                 max = arr[i];
         
         return max;
}
 
 
// Recursive function to return gcd of a and b
static int gcd(int a, int b)
{
 if (b == 0)
        return a;
      return gcd(b, a % b);
}
 
 
// Function to find the total subsequences
// having GCD = X
static int totalValidSubsequences(int[] arr,
                                      int X, int N)
    {
        // Find the maximum element of
        // the array
        int mx = max(arr);
 
        // Check if X is greater than mx
        if (X > mx) {
            return 0;
        }
        // Make a 2-d dp table of
        // size [n+1, mx + 1]
        int[,] dp = new int[N + 1, mx + 1];
 
        // Base Case
        dp[0, 0] = 1;
 
        for (int i = 0; i < N; i++) {
 
            // Iterate through all possible
            // indexes
            for (int j = 0; j <= mx; j++) {
 
                // Iterate through all
                // possible values
 
                // Case 1. Skip the element
                dp[i + 1, j] += dp[i, j];
 
                // Case 2. Skip the current element
                dp[i + 1, gcd(j, arr[i])] += dp[i, j];
            }
        }
 
        // Return the answer dp[N][X]
        return dp[N, X];
    }
 
 
 
// Driver Code
public static void Main()
{
   int[] arr = { 6, 4, 30 };
           int X = 2;
        int N = arr.Length;
           Console.Write(totalValidSubsequences(arr, X, N));
}
}
 
// This code is contributed by _saurabh_jaiswal

Javascript




<script>
       // JavaScript Program to implement
       // the above approach
       // Recursive function to return gcd of a and b
       function __gcd(a, b) {
           if (b == 0)
               return a;
           return __gcd(b, a % b);
       }
 
 
       // Function to find the total subsequences
       // having GCD = X
       function totalValidSubsequences(
           arr, X, N)
       {
           // Find the maximum element of
           // the array
           let mx = arr[0];
 
           for (let i = 1; i < arr.length; i++) {
               mx = Math.max(mx, arr[i]);
           }
 
           // Check if X is greater than mx
           if (X > mx) {
               return 0;
           }
           // Make a 2-d dp table of
           // size [n+1, mx + 1]
 
           let dp = new Array(N + 1);
           for (let i = 0; i < N + 1; i++) {
               dp[i] = new Array(mx + 1).fill(0)
           }
 
 
           // Base Case
           dp[0][0] = 1;
 
           for (let i = 0; i < N; i++) {
 
               // Iterate through all possible
               // indexes
               for (let j = 0; j <= mx; j++) {
 
                   // Iterate through all
                   // possible values
 
                   // Case 1. Skip the element
                   dp[i + 1][j] += dp[i][j];
 
                   // Case 2. Skip the current element
                   dp[i + 1][__gcd(j, arr[i])] += dp[i][j];
               }
           }
 
           // Return the answer dp[N][X]
           return dp[N][X];
       }
 
       // Driver Code
       let arr = [6, 4, 30];
       let X = 2;
       let N = arr.length;
       document.write(totalValidSubsequences(arr, X, N));
        
    // This code is contributed by Potta Lokesh
   </script>
Output: 
3

 

Time Complexity: O(N*M), where M is the maximum element of the array.
Auxiliary Space: O(N*M)




My Personal Notes arrow_drop_up
Recommended Articles
Page :

Start Your Coding Journey Now!