Count ways to split array into two subarrays with equal GCD
Last Updated :
22 Nov, 2021
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: 2
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: 2
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++
// 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;
}
Java
// 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
Python3
# 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
C#
// 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
JavaScript
<script>
// Javascript program to implement
// the above approach
function gcd(a, 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.
function cntWaysToSplitArrayTwo(arr, N)
{
// Stores prefix GCD
// of the array
let prefixGCD = [];
// Update prefixGCD[0]
prefixGCD[0] = arr[0];
// Stores suffix GCD
// of the array
let suffixGCD = [];
// Update suffixGCD[N - 1]
suffixGCD[N - 1] = arr[N - 1];
// Traverse the array
for(let i = 1; i < N; i++)
{
// Update prefixGCD[i]
prefixGCD[i] = gcd(prefixGCD[i - 1],
arr[i]);
}
// Traverse the array
for(let 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
let cntWays = 0;
// Traverse prefixGCD[] and suffixGCD[]
for(let 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
let arr = [ 8, 4, 4, 8, 12 ];
let N = arr.length;
document.write(cntWaysToSplitArrayTwo(arr, N));
// This code is contributed by code_hunt
</script>
Time Complexity: O(N)
Auxiliary Space: O(N)
Similar Reads
Number of subarrays with GCD equal to 1 in O(n) time Given an array arr[] of size N, the task is to find the maximum number of sub-arrays such that the GCD(Greatest Common Factor) of all elements of each sub-array is equal to 1 in O(n). Examples: Input: arr[] = {4, 2, 3, 0, 1, 8, 16, 1}.Output: 3Explanation: GCD of subarray {4, 2, 3} is 1, GCD of suba
6 min read
Check if an array can be split into subarrays with GCD exceeding K Given an array arr[] of N integers and a positive integer K, the task is to check if it is possible to split this array into distinct contiguous subarrays such that the Greatest Common Divisor of all elements of each subarray is greater than K. Note: Each array element can be a part of exactly one s
5 min read
Count Subarray of size K in given Array with given LCM Given an array arr[] of length N, the task is to find the number of subarrays where the least common multiple (LCM) of the subarray is equal to K and the size of that subarray is S. Examples: Input: arr[] = {1, 2, 3, 4, 5, 6}, K = 6, S = 2Output: 1Explanation: {1, 2, 3 }, {2, 3}, {6}There are 3 suba
8 min read
Number of subarrays with GCD equal to 1 Given an array arr[], the task is to find the number of sub-arrays with a GCD value equal to 1. Examples: Input: arr[] = {1, 1, 1} Output: 6 All the subarrays of the given array will have GCD equal to 1.Input: arr[] = {2, 2, 2} Output: 0 Approach: The key observation is that if the GCD of all the el
5 min read
Count number of subsets of a set with GCD equal to a given number Given a set of positive integer elements, find the count of subsets with GCDs equal to given numbers.Examples: Input: arr[] = {2, 3, 4}, gcd[] = {2, 3} Output: Number of subsets with gcd 2 is 2 Number of subsets with gcd 3 is 1 The two subsets with GCD equal to 2 are {2} and {2, 4}. The one subset w
11 min read