# Maximize the number of subarrays with XOR as zero in C++

C++Server Side ProgrammingProgramming

We are given an array Arr[] containing integer values. The goal is to find the maximum number of subarrays with XOR as 0. The bits of any subarray can be swapped any number of times.

Note:- 1<=Arr[i]<=1018

In order to make any subarray’s XOR as 0 by swapping bits, two conditions have to be met:-

• If the number of set bits in range left to right is even.

• For any given range sum of bits <= 2 (largest number in set bits)

Let us see various input output scenarios for this -

In −Arr[] = { 1,2,5,4 }

Out

Subarrays satisfying only 1st condition : 4

Subarrays satisfying both condition : 3

In − Arr[] = { 3,7,2,9 }

Out

Subarrays satisfying only 1st condition : 6

Subarrays satisfying both condition : 3

## Approach used in the below program is as follows −

In this approach we observed that in order to make any subarray’s XOR as 0 by swapping bits, two conditions have to be met:- If the number of set bits in range left to right is even or for any given range sum of bits <= 2 (largest number in set bits)

• Take the input array Arr[] and calculate its length.

• Function removeSubarr(int arr[], int len) returns the count of subarrays not satisfying condition 2.

• Take the initial count as 0.

• Iterate array using for loop and take variables sum and maxVal.

• Take another for loop to iterate in range of 60 subarrays as beyond 60 the condition 2 can never be false.

• Add element to sum and take maximum in maxVal.

• If sum is even and 2 * maxVal > sum then increment count as condition 2 is not met.

• At the end of both loops return count.

• Function findSubarrays(int arr1[], int len1) takes an input array and its length and returns the count of subarrays satisfying both conditions mentioned above.

• Take a prefix array to calculate the count of subarrays that follow condition 1 only.

• Traverse array using for loop and set each element with __builtin_popcountll(arr1[i]) which is the number of set bits in it.

• Populate prefix array using for loop and set prefix[i] = prefix[i] + prefix[i - 1] where except first element.

• Count odd and even values in the prefix array.

• Set tmp1= ( oddcount * (oddcount-1) )/2 and tmp2= ( evencount * (evencount-1) )/2 and result as sum of both.

• Result will be the sum of subarrays satisfying condition 1 only.

• Print result.

• Now update result with result=result - removeSubarr(arr1, len1).

• Now the result contains subarrays satisfying both conditions.

• Print result again.

## Example

#include <bits/stdc++.h>
using namespace std;
// Function to count subarrays not satisfying condition 2
int removeSubarr(int arr[], int len){
int count = 0;
for (int i = 0; i < len; i++){
int sum = 0;
int maxVal = 0;

for (int j = i; j < min(len, i + 60); j++){
sum = sum + arr[j];
maxVal = arr[j] > maxVal ? arr[j]: maxVal;

if (sum % 2 == 0){
if( 2 * maxVal > sum)
{ count++; }
}
}
}
return count;
}
int findSubarrays(int arr1[], int len1){
int prefix[len1];
int oddcount, evencount;
int result;
for (int i = 0; i < len1; i++)
{ arr1[i] = __builtin_popcountll(arr1[i]); }

for (int i = 0; i < len1; i++){
prefix[i] = arr1[i];
if (i != 0)
{ prefix[i] = prefix[i] + prefix[i - 1]; }
}
oddcount = evencount = 0;
for (int i = 0; i < len1; i++){
if (prefix[i] % 2 == 0)
{ evencount = evencount +1; }
else
{ oddcount = oddcount +1; }

}
evencount++;
int tmp1= ( oddcount * (oddcount-1) )/2;
int tmp2= ( evencount * (evencount-1) )/2;
result = tmp1+tmp2;
cout << "Subarrays satisfying only 1st condition : "<<result << endl;
cout << "Subarrays satisfying both condition : ";
result = result - removeSubarr(arr1, len1);
return result;
}
int main()
{ int Arr[] = { 1,2,5,4 };
int length = sizeof(Arr) / sizeof(Arr[0]);
cout << findSubarrays(Arr, length);
return 0;
}

## Output

If we run the above code it will generate the following Out

Subarrays satisfying only 1st condition : 4
Subarrays satisfying both condition : 3
Published on 22-Oct-2021 08:52:03