Number of subarrays such that XOR of one half is equal to the other
Last Updated :
15 Nov, 2022
Given an array of N numbers, the task is to find the number of sub-arrays (size of the sub-array should be an even number) of the given array such that after dividing the sub-array in two equal halves, bitwise XOR of one half of the sub-array will be equal to bitwise XOR of the other half.
Examples:
Input : N = 6, arr[] = {3, 2, 2, 3, 7, 6}
Output : 3
Valid sub-arrays are {3, 2, 2, 3}, {2, 2},
and {2, 3, 7, 6}
Input : N = 5, arr[] = {1, 2, 3, 4, 5}
Output : 1
Input : N = 3, arr[] = {42, 4, 2}
Output : 0
Approach: If an array is divided into two equal halves and XOR of one half is equal to the other, it means that XOR of whole of the array should be 0, because A^A = 0. Now, to solve the above problem find the prefix XOR’s of all the elements of the given array starting from left.
Suppose, a sub-array starts from l and ends at r, then (r-l+1) should be even. Also, to find XOR of a given range (l, r) subtract prefix XOR at (l – 1) with prefix XOR at r.
Since, (r – l + 1) is even, hence, if r is even then l should be odd and vice versa. Now, divide your prefixes into two groups, one should be the group of prefixes of odd indexes and the other should be of even indexes. Now, start traversing the prefix array from left to right and see how many time this particular prefix A has already occurred in its respective group, i.e. prefixes at even indexes should be checked in even prefix group and prefixes at odd indexes in odd prefix group (because if r is even then (l-1) is also even, similar logic is applied if r is odd).
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int findSubarrCnt( int arr[], int n)
{
int ans = 0, XOR = 0;
int prefix[n];
for ( int i = 0; i < n; ++i) {
XOR = XOR ^ arr[i];
prefix[i] = XOR;
}
unordered_map< int , int > oddGroup, evenGroup;
oddGroup[0] = 1;
for ( int i = 0; i < n; ++i) {
if (i & 1) {
ans += oddGroup[prefix[i]];
++oddGroup[prefix[i]];
}
else {
ans += evenGroup[prefix[i]];
++evenGroup[prefix[i]];
}
}
return ans;
}
int main()
{
int N = 6;
int arr[] = { 3, 2, 2, 3, 7, 6 };
cout << findSubarrCnt(arr, N);
return 0;
}
|
Java
import java.util.*;
class GFG
{
static int findSubarrCnt( int arr[], int n)
{
int ans = 0 , XOR = 0 ;
int prefix[] = new int [n];
for ( int i = 0 ; i < n; ++i)
{
XOR = XOR ^ arr[i];
prefix[i] = XOR;
}
HashMap<Integer, Integer> evenGroup = new HashMap<>();
HashMap<Integer, Integer> oddGroup = new HashMap<>();
oddGroup.put( 0 , 1 );
for ( int i = 0 ; i < n; ++i)
{
if (i % 2 == 1 )
{
if (oddGroup.containsKey(prefix[i]))
{
ans += oddGroup.get(prefix[i]);
oddGroup.put(prefix[i],oddGroup.get(prefix[i] + 1 ));
}
else
{
oddGroup.put(prefix[i], 1 );
}
}
else
{
if (evenGroup.containsKey(prefix[i]))
{
ans += evenGroup.get(prefix[i]);
evenGroup.put(prefix[i],evenGroup.get(prefix[i] + 1 ));
}
else
{
evenGroup.put(prefix[i], 1 );
}
}
}
return ans;
}
public static void main (String[] args)
{
int arr[] = { 3 , 2 , 2 , 3 , 7 , 6 };
int N = arr.length;
System.out.println(findSubarrCnt(arr, N));
}
}
|
Python3
def findSubarrCnt(arr, n) :
ans = 0 ; XOR = 0 ;
prefix = [ 0 ] * n;
for i in range (n) :
XOR = XOR ^ arr[i];
prefix[i] = XOR;
oddGroup = dict .fromkeys(prefix, 0 )
evenGroup = dict .fromkeys(prefix, 0 )
oddGroup[ 0 ] = 1 ;
for i in range (n) :
if (i & 1 ) :
ans + = oddGroup[prefix[i]];
oddGroup[prefix[i]] + = 1 ;
else :
ans + = evenGroup[prefix[i]];
evenGroup[prefix[i]] + = 1 ;
return ans;
if __name__ = = "__main__" :
N = 6 ;
arr = [ 3 , 2 , 2 , 3 , 7 , 6 ];
print (findSubarrCnt(arr, N));
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static int findSubarrCnt( int [] arr, int n)
{
int ans = 0, XOR = 0;
int [] prefix = new int [n];
for ( int i = 0; i < n; ++i)
{
XOR = XOR ^ arr[i];
prefix[i] = XOR;
}
Dictionary< int , int > evenGroup = new Dictionary< int , int >();
Dictionary< int , int > oddGroup = new Dictionary< int , int >();
oddGroup[0] = 1;
for ( int i = 0; i < n; ++i)
{
if (i % 2== 1)
{
if (oddGroup.ContainsKey(prefix[i]))
{
ans += oddGroup[prefix[i]];
oddGroup[prefix[i]]++;
}
else
{
oddGroup[prefix[i]] = 1;
}
}
else
{
if (evenGroup.ContainsKey(prefix[i]))
{
ans += evenGroup[prefix[i]];
evenGroup[prefix[i]]++;
}
else
{
evenGroup[prefix[i]] = 1;
}
}
}
return ans;
}
public static void Main ()
{
int [] arr = { 3, 2, 2, 3, 7, 6 };
int N = arr.Length;
Console.WriteLine(findSubarrCnt(arr, N));
}
}
|
Javascript
<script>
function findSubarrCnt(arr, n)
{
let ans = 0, XOR = 0;
let prefix = Array.from({length: n}, (_, i) => 0);
for (let i = 0; i < n; ++i)
{
XOR = XOR ^ arr[i];
prefix[i] = XOR;
}
let evenGroup = new Map();
let oddGroup = new Map();
oddGroup.set(0, 1);
for (let i = 0; i < n; ++i)
{
if (i % 2== 1)
{
if (oddGroup.has(prefix[i]))
{
ans += oddGroup.get(prefix[i]);
oddGroup.set(prefix[i],oddGroup.get(prefix[i] + 1));
}
else
{
oddGroup.set(prefix[i], 1);
}
}
else
{
if (evenGroup.has(prefix[i]))
{
ans += evenGroup.get(prefix[i]);
evenGroup.set(prefix[i],evenGroup.get(prefix[i] + 1));
}
else
{
evenGroup.set(prefix[i], 1);
}
}
}
return ans;
}
let arr = [ 3, 2, 2, 3, 7, 6 ];
let N = arr.length;
document.write(findSubarrCnt(arr, N));
</script>
|
Time Complexity: O(N), where N is the size of the given input array.
Auxiliary Space: O(N), where N is the size of the given input array.
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...