Skip to content
Related Articles

Related Articles

Count ways to split array into two subarrays with equal GCD
  • Last Updated : 01 Dec, 2020

Given an array, arr[] of size N, the task is to count the number of ways to split given array elements into two subarrays such that GCD of both the subarrays are equal.

Examples:

Input: arr[] = {8, 4, 4, 8, 12} 
Output:
Explanation: 
Possible ways to split the array two groups of equal GCD are: { {{arr[0], arr[1]}, {arr[2], arr[3], arr[4]}}, {{arr[0], arr[1], arr[2]}, {arr[3], arr[4]}} }. 
Therefore, the required output is 2. 

Input: arr[] = {1, 2, 4, 6, 5} 
Output:
 

Naive Approach: The simplest approach to solve this problem is to traverse the array and at each array index, partition the array into two subarrays and check if the GCD of both the subarrays are equal or not. If found to be true, then increment the count of such subarrays. Finally, print the count.



Time Complexity: O(N2) 
Auxiliary Space: O(N)

Efficient Approach: To optimize the above approach, the idea is to use Prefix Sum Array technique. Follow the steps below to solve the problem:

  • Initialize a variable, say cntWays to store count of ways to split the array into two subarrays such that GCD of both the subarrays are equal.
  • Initialize an array, say prefixGCD[] to store the prefix GCD of array elements.
  • Initialize an array, say suffixGCD[] to store the suffix GCD of array elements.
  • Traverse prefixGCD[] and suffixGCD[] arrays using variable i and check if prefixGCD[i] and suffixGCD[i + 1] are equal or not. If found to be true, then increment the value of cntWays.
  • Finally, print the value of cntWays.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to implement
// the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to count number of ways to split
// array into two groups with equal GCD value.
int cntWaysToSplitArrayTwo(int arr[], int N)
{
    // Stores prefix GCD
    // of the array
    int prefixGCD[N];
 
    // Update prefixGCD[0]
    prefixGCD[0] = arr[0];
 
    // Stores suffix GCD
    // of the array
    int suffixGCD[N];
 
    // Update suffixGCD[N - 1]
    suffixGCD[N - 1] = arr[N - 1];
 
    // Traverse the array
    for (int i = 1; i < N; i++) {
 
        // Update prefixGCD[i]
        prefixGCD[i]
            = __gcd(prefixGCD[i - 1],
                    arr[i]);
    }
 
    // Traverse the array
    for (int i = N - 2; i >= 0; i--) {
 
        // Update prefixGCD[i]
        suffixGCD[i]
            = __gcd(suffixGCD[i + 1],
                    arr[i]);
    }
 
    // Stores count of ways to split array
    // into two groups with equal GCD
    int cntWays = 0;
 
    // Traverse prefixGCD[] and suffixGCD[]
    for (int i = 0; i < N - 1; i++) {
 
        // If GCD of both groups equal
        if (prefixGCD[i]
            == suffixGCD[i + 1]) {
 
            // Update cntWays
            cntWays += 1;
        }
    }
 
    return cntWays;
}
 
// Driver Code
int main()
{
    int arr[] = { 8, 4, 4, 8, 12 };
    int N = sizeof(arr) / sizeof(arr[0]);
    cout << cntWaysToSplitArrayTwo(arr, N);
 
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to implement
// the above approach
import java.io.*;
import java.util.*;
 
class GFG{
  
static int gcd(int a, int b)
{
     
    // Everything divides 0
    if (a == 0)
      return b;
    if (b == 0)
      return a;
   
    // Base case
    if (a == b)
        return a;
   
    // a is greater
    if (a > b)
        return gcd(a - b, b);
         
    return gcd(a, b - a);
}
     
// Function to count number of ways to split
// array into two groups with equal GCD value.
static int cntWaysToSplitArrayTwo(int arr[],
                                  int N)
{
     
    // Stores prefix GCD
    // of the array
    int prefixGCD[] = new int[N];
     
    // Update prefixGCD[0]
    prefixGCD[0] = arr[0];
  
    // Stores suffix GCD
    // of the array
    int suffixGCD[] = new int[N];
  
    // Update suffixGCD[N - 1]
    suffixGCD[N - 1] = arr[N - 1];
  
    // Traverse the array
    for(int i = 1; i < N; i++)
    {
         
        // Update prefixGCD[i]
        prefixGCD[i] = gcd(prefixGCD[i - 1],
                                 arr[i]);
    }
  
    // Traverse the array
    for(int i = N - 2; i >= 0; i--)
    {
         
        // Update prefixGCD[i]
        suffixGCD[i] = gcd(suffixGCD[i + 1],
                                 arr[i]);
    }
  
    // Stores count of ways to split array
    // into two groups with equal GCD
    int cntWays = 0;
  
    // Traverse prefixGCD[] and suffixGCD[]
    for(int i = 0; i < N - 1; i++)
    {
         
        // If GCD of both groups equal
        if (prefixGCD[i] == suffixGCD[i + 1])
        {
             
            // Update cntWays
            cntWays += 1;
        }
    }
    return cntWays;
}
   
// Driver Code
public static void main(String[] args)
{
    int arr[] = { 8, 4, 4, 8, 12 };
    int N = arr.length;
     
    System.out.print(cntWaysToSplitArrayTwo(arr, N));
}
}
 
// This code is contributed by sanjoy_62

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program to implement
# the above approach
import math
 
# Function to count number of ways to split
# array into two groups with equal GCD value.
def cntWaysToSplitArrayTwo(arr, N):
     
    # Stores prefix GCD
    # of the array
    prefixGCD = [0] * N
  
    # Update prefixGCD[0]
    prefixGCD[0] = arr[0]
  
    # Stores suffix GCD
    # of the array
    suffixGCD = [0] * N
  
    # Update suffixGCD[N - 1]
    suffixGCD[N - 1] = arr[N - 1]
  
    # Traverse the array
    for i in range(N):
  
        # Update prefixGCD[i]
        prefixGCD[i] = math.gcd(prefixGCD[i - 1], arr[i])
     
    # Traverse the array
    for i in range(N - 2, -1, -1):
  
        # Update prefixGCD[i]
        suffixGCD[i] = math.gcd(suffixGCD[i + 1], arr[i])
     
    # Stores count of ways to split array
    # into two groups with equal GCD
    cntWays = 0
  
    # Traverse prefixGCD[] and suffixGCD[]
    for i in range(N - 1):
         
        # If GCD of both groups equal
        if (prefixGCD[i] == suffixGCD[i + 1]):
             
            # Update cntWays
            cntWays += 1
  
    return cntWays
 
# Driver Code
arr = [ 8, 4, 4, 8, 12 ]
N = len(arr)
 
print(cntWaysToSplitArrayTwo(arr, N))
 
# This code is contributed by susmitakundugoaldanga

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program to implement
// the above approach
using System;
 
class GFG{
  
static int gcd(int a, int b)
{
     
    // Everything divides 0
    if (a == 0)
      return b;
    if (b == 0)
      return a;
   
    // Base case
    if (a == b)
        return a;
   
    // a is greater
    if (a > b)
        return gcd(a - b, b);
         
    return gcd(a, b - a);
}
     
// Function to count number of ways to split
// array into two groups with equal GCD value.
static int cntWaysToSplitArrayTwo(int []arr,
                                  int N)
{
     
    // Stores prefix GCD
    // of the array
    int []prefixGCD = new int[N];
     
    // Update prefixGCD[0]
    prefixGCD[0] = arr[0];
  
    // Stores suffix GCD
    // of the array
    int []suffixGCD = new int[N];
  
    // Update suffixGCD[N - 1]
    suffixGCD[N - 1] = arr[N - 1];
  
    // Traverse the array
    for(int i = 1; i < N; i++)
    {
         
        // Update prefixGCD[i]
        prefixGCD[i] = gcd(prefixGCD[i - 1],
                                 arr[i]);
    }
  
    // Traverse the array
    for(int i = N - 2; i >= 0; i--)
    {
         
        // Update prefixGCD[i]
        suffixGCD[i] = gcd(suffixGCD[i + 1],
                                 arr[i]);
    }
  
    // Stores count of ways to split array
    // into two groups with equal GCD
    int cntWays = 0;
  
    // Traverse prefixGCD[] and suffixGCD[]
    for(int i = 0; i < N - 1; i++)
    {
         
        // If GCD of both groups equal
        if (prefixGCD[i] == suffixGCD[i + 1])
        {
             
            // Update cntWays
            cntWays += 1;
        }
    }
    return cntWays;
}
   
// Driver Code
public static void Main(String[] args)
{
    int []arr = { 8, 4, 4, 8, 12 };
    int N = arr.Length;
     
    Console.Write(cntWaysToSplitArrayTwo(arr, N));
}
}
 
// This code is contributed by Princi Singh

chevron_right


Output: 

2

 

Time Complexity: O(N) 
Auxiliary Space: O(N)

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.

My Personal Notes arrow_drop_up
Recommended Articles
Page :