Skip to content
Related Articles

Related Articles

Count subsequences with GCD equal to X

Improve Article
Save Article
Like Article
  • 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:

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!