Count ways to split array into three non-empty subarrays having equal Bitwise XOR values
Last Updated :
29 Jun, 2021
Given an array arr[] consisting of N non-negative integers, the task is to count the number of ways to split the array into three different non-empty subarrays such that Bitwise XOR of each subarray is equal.
Examples:
Input: arr[] = {7, 0, 5, 2, 7}
Output: 2
Explanation: All possible ways are:
{{7}, {0, 5, 2}, {7}} where XOR value of each subarray is 7
{{7, 0}, {5, 2}, {7}} where XOR value of each subarray is 7
Input: arr[] = {3, 1, 4}
Output: 0
Naive Approach: The simplest approach is to split the array into three non-empty subarrays using three loops and check whether the XOR of each subarray are equal or not. If the given condition holds true, then increase the final count. Print the final count obtained.
Time Complexity: O(N3)
Auxiliary Space: O(1)
Efficient Approach: The above approach can be optimized based on the following observations:
- Let xor_arr be the XOR of all elements of the array arr[].
- If arr[] can be split into three different subarrays of equal XOR values, then XOR of all elements in each subarray will be equal to xor_arr.
- So, the idea is to find all the prefix and suffix arrays with XOR value equal to xor_arr.
- If the total length of such a prefix and suffix array is less than N, then there exists another subarray between them with XOR value equal to xor_arr.
Hence, count the total number of all such prefix and suffix arrays that satisfy the above condition. Follow the steps below to solve the given problem:
- Store the XOR of all elements of the array, arr[] in a variable xor_arr.
- Create an array, pref_ind[] to store the ending points of every prefix array whose XOR value is equal to xor_arr.
- Traverse the array, arr[] and insert the ending points of every prefix array whose XOR value is equal to xor_arr in pref_ind.
- Create another array, suff_inds[] of size N where suff_inds[i] stores the total number of suffix arrays with XOR value equal to xor_arr whose starting point is greater than or equal to i.
- Traverse the array, arr[] in reverse order to fill the suff_inds[] array. If the current suffix array XOR value equals xor_arr, then increment suff_inds[i] by 1. Also, add the value of suff_inds[i+1] to suff_inds[i].
- For every element idx in pref_ind if the value of idx < N-1, then add the value of suff_inds[idx + 2] to the final count.
- Finally, print the value of the final count as the result.
Below is the implementation of the above approach:
C++
// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
// Function to count ways to split array
// into three subarrays with equal Bitwise XOR
int countWays(int arr[], int N)
{
// Stores the XOR value of arr[]
int arr_xor = 0;
// Update the value of arr_xor
for (int i = 0; i < N; i++)
arr_xor ^= arr[i];
// Stores the XOR value of prefix
// and suffix array respectively
int pref_xor = 0, suff_xor = 0;
// Stores the ending points of all
// the required prefix arrays
vector<int> pref_ind;
// Stores the count of suffix arrays
// whose XOR value is equal to the
// total XOR value at each index
int suff_inds[N + 1];
memset(suff_inds, 0, sizeof suff_inds);
// Find all prefix arrays with
// XOR value equal to arr_xor
for (int i = 0; i < N; i++) {
// Update pref_xor
pref_xor ^= arr[i];
if (pref_xor == arr_xor)
pref_ind.push_back(i);
}
// Fill the values of suff_inds[]
for (int i = N - 1; i >= 0; i--) {
// Update suff_xor
suff_xor ^= arr[i];
// Update suff_inds[i]
suff_inds[i] += suff_inds[i + 1];
if (suff_xor == arr_xor)
suff_inds[i]++;
}
// Stores the total number of ways
int tot_ways = 0;
// Count total number of ways
for (int idx : pref_ind) {
if (idx < N - 1)
tot_ways += suff_inds[idx + 2];
}
// Return the final count
return tot_ways;
}
// Driver Code
int main()
{
// Given Input
int arr[] = { 7, 0, 5, 2, 7 };
int N = sizeof(arr) / sizeof(arr[0]);
// Function Call
cout << countWays(arr, N);
return 0;
}
Java
// Java program for the above approach
import java.lang.*;
import java.util.*;
class GFG
{
// Function to count ways to split array
// into three subarrays with equal Bitwise XOR
static int countWays(int arr[], int N)
{
// Stores the XOR value of arr[]
int arr_xor = 0;
// Update the value of arr_xor
for (int i = 0; i < N; i++)
arr_xor ^= arr[i];
// Stores the XOR value of prefix
// and suffix array respectively
int pref_xor = 0, suff_xor = 0;
// Stores the ending points of all
// the required prefix arrays
ArrayList<Integer> pref_ind=new ArrayList<>();
// Stores the count of suffix arrays
// whose XOR value is equal to the
// total XOR value at each index
int[] suff_inds= new int[N + 1];
// Find all prefix arrays with
// XOR value equal to arr_xor
for (int i = 0; i < N; i++) {
// Update pref_xor
pref_xor ^= arr[i];
if (pref_xor == arr_xor)
pref_ind.add(i);
}
// Fill the values of suff_inds[]
for (int i = N - 1; i >= 0; i--) {
// Update suff_xor
suff_xor ^= arr[i];
// Update suff_inds[i]
suff_inds[i] += suff_inds[i + 1];
if (suff_xor == arr_xor)
suff_inds[i]++;
}
// Stores the total number of ways
int tot_ways = 0;
// Count total number of ways
for (Integer idx : pref_ind) {
if (idx < N - 1)
tot_ways += suff_inds[idx + 2];
}
// Return the final count
return tot_ways;
}
// Driver code
public static void main(String[] args)
{
// Given Input
int arr[] = { 7, 0, 5, 2, 7 };
int N = arr.length;
// Function Call
System.out.println(countWays(arr, N));
}
}
// This code is contributed by offbeat
Python3
# Python3 program for the above approach
# Function to count ways to split array
# into three subarrays with equal Bitwise XOR
def countWays(arr, N):
# Stores the XOR value of arr[]
arr_xor = 0
# Update the value of arr_xor
for i in range(N):
arr_xor ^= arr[i]
# Stores the XOR value of prefix
# and suffix array respectively
pref_xor, suff_xor = 0, 0
# Stores the ending points of all
# the required prefix arrays
pref_ind = []
# Stores the count of suffix arrays
# whose XOR value is equal to the
# total XOR value at each index
suff_inds = [0] * (N + 1)
# memset(suff_inds, 0, sizeof suff_inds)
# Find all prefix arrays with
# XOR value equal to arr_xor
for i in range(N):
# Update pref_xor
pref_xor ^= arr[i]
if (pref_xor == arr_xor):
pref_ind.append(i)
# Fill the values of suff_inds[]
for i in range(N - 1, -1, -1):
# Update suff_xor
suff_xor ^= arr[i]
# Update suff_inds[i]
suff_inds[i] += suff_inds[i + 1]
if (suff_xor == arr_xor):
suff_inds[i] += 1
# Stores the total number of ways
tot_ways = 0
# Count total number of ways
for idx in pref_ind:
if (idx < N - 1):
tot_ways += suff_inds[idx + 2]
# Return the final count
return tot_ways
# Driver Code
if __name__ == '__main__':
# Given Input
arr = [ 7, 0, 5, 2, 7 ]
N = len(arr)
# Function Call
print (countWays(arr, N))
# This code is contributed by mohit kumar 29
C#
// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG {
// Function to count ways to split array
// into three subarrays with equal Bitwise XOR
static int countWays(int[] arr, int N)
{
// Stores the XOR value of arr[]
int arr_xor = 0;
// Update the value of arr_xor
for (int i = 0; i < N; i++)
arr_xor ^= arr[i];
// Stores the XOR value of prefix
// and suffix array respectively
int pref_xor = 0, suff_xor = 0;
// Stores the ending points of all
// the required prefix arrays
List<int> pref_ind = new List<int>();
// Stores the count of suffix arrays
// whose XOR value is equal to the
// total XOR value at each index
int[] suff_inds = new int[N + 1];
// Find all prefix arrays with
// XOR value equal to arr_xor
for (int i = 0; i < N; i++) {
// Update pref_xor
pref_xor ^= arr[i];
if (pref_xor == arr_xor)
pref_ind.Add(i);
}
// Fill the values of suff_inds[]
for (int i = N - 1; i >= 0; i--) {
// Update suff_xor
suff_xor ^= arr[i];
// Update suff_inds[i]
suff_inds[i] += suff_inds[i + 1];
if (suff_xor == arr_xor)
suff_inds[i]++;
}
// Stores the total number of ways
int tot_ways = 0;
// Count total number of ways
foreach(int idx in pref_ind)
{
if (idx < N - 1)
tot_ways += suff_inds[idx + 2];
}
// Return the final count
return tot_ways;
}
// Driver code
public static void Main(string[] args)
{
// Given Input
int[] arr = { 7, 0, 5, 2, 7 };
int N = arr.Length;
// Function Call
Console.WriteLine(countWays(arr, N));
}
}
// This code is contributed by ukasp.
JavaScript
<script>
// JavaScript program for the above approach
// Function to count ways to split array
// into three subarrays with equal Bitwise XOR
function countWays(arr, N)
{
// Stores the XOR value of arr[]
let arr_xor = 0;
// Update the value of arr_xor
for (let i = 0; i < N; i++)
arr_xor ^= arr[i];
// Stores the XOR value of prefix
// and suffix array respectively
let pref_xor = 0, suff_xor = 0;
// Stores the ending points of all
// the required prefix arrays
let pref_ind = [];
// Stores the count of suffix arrays
// whose XOR value is equal to the
// total XOR value at each index
let suff_inds = new Array(N + 1);
suff_inds.fill(0);
// Find all prefix arrays with
// XOR value equal to arr_xor
for (let i = 0; i < N; i++) {
// Update pref_xor
pref_xor ^= arr[i];
if (pref_xor == arr_xor)
pref_ind.push(i);
}
// Fill the values of suff_inds[]
for (let i = N - 1; i >= 0; i--) {
// Update suff_xor
suff_xor ^= arr[i];
// Update suff_inds[i]
suff_inds[i] += suff_inds[i + 1];
if (suff_xor == arr_xor)
suff_inds[i]++;
}
// Stores the total number of ways
let tot_ways = 0;
// Count total number of ways
for (let idx of pref_ind) {
if (idx < N - 1)
tot_ways += suff_inds[idx + 2];
}
// Return the final count
return tot_ways;
}
// Driver Code
// Given Input
let arr = [ 7, 0, 5, 2, 7 ];
let N = arr.length;
// Function Call
document.write(countWays(arr, N));
</script>
Time Complexity: O(N)
Auxiliary Space: O(N)
Similar Reads
Count ways to split a Binary String into three substrings having equal count of zeros Given binary string str, the task is to count the total number of ways to split the given string into three non-overlapping substrings having the same number of 0s. Examples: Input: str = "01010" Output: 4 Explanation: The possible splits are: [0, 10, 10], [01, 01, 0], [01, 0, 10], [0, 101, 0] Input
15+ min read
Count the number of ways to divide an array into three contiguous parts having equal sum Given an array of n numbers. Our task is to find out the number of ways to divide the array into three contiguous parts such that the sum of three parts is equal. In other words, we need to find the number of index pairs i and j such that sum of elements from 0 to i-1 is equal to the sum of elements
15+ min read
Check if an array can be split into K non-overlapping subarrays whose Bitwise AND values are equal Given an array arr[] of size N and a positive integer K, the task is to check if the array can be split into K non-overlapping and non-empty subarrays such that Bitwise AND of all the subarrays are equal. If found to be true, then print "YES". Otherwise, print "NO". Examples: Input: arr[] = { 3, 2,
11 min read
Count even length subarrays having bitwise XOR equal to 0 Given an array arr[] of size N, the task is to count all possible even length subarrays having bitwise XOR of subarray elements equal to 0. Examples: Input: arr[] = {2, 2, 3, 3, 6, 7, 8}Output: 3Explanation:Subarrays having XOR of elements equal to 0 are: {{2, 2}, {3, 3}, {2, 2, 3, 3}}Therefore, the
13 min read
Find a K-length subarray having Bitwise XOR equal to that of remaining array elements Given an array arr[] of size N, the task is to check if any subarray of size K exists in the array or not, whose Bitwise XOR is equal to the Bitwise XOR of the remaining array elements. If found to be true, then print "YES". Otherwise, print "NO". Examples: Input: arr[] = { 2, 3, 3, 5, 7, 7, 3, 4 },
9 min read