Find the Number Whose Sum of XOR with Given Array Range is Maximum using C++

To solve a problem in which we are given an array and some queries. Now in each query, we are given a range. Now we need to find a number such that the sum of their xor with x is maximized, for example

Input : A = {20, 11, 18, 2, 13}
Three queries as (L, R) pairs
1 3
3 5
2 4
Output : 2147483629
2147483645
2147483645

In this problem, we are going to take a prefix count of 1’s present in the numbers at each position now as we have precalculated our number of ones, so for finding the number of ones in the given range from L to R, we need to subtract presumed till R with presumed till L.

Approach to Find the Solution

In this approach, as we are required to find the maximum sum, so we need to make the majority of bits of xor equal to 1; hence we check if for any bit if one is more than the number of 0’s so we reset that bit of x as now majority of number has that bit equal to 1 so when we pair that majority 1’s with 0’s so eventually we have the majority of that bit equal to 1 thus this is how we maximize our answer.

Example

C++ Code for the Above Approach

#include <bits/stdc++.h>
using namespace std;
#define MAX 2147483647 // 2^31 - 1
int prefix[100001][32]; // the prefix array
void prefix_bit(int A[], int n){ // taking prefix count of 1's present
for (int j = 0; j < 32; j++) // we keep 0th count as 0 and our prefix array starts with index 1
prefix[0][j] = 0;
for (int i = 1; i <= n; i++){ // making our prefix array
int a = A[i - 1]; // ith element
for (int j = 0; j < 32; j++){ // as our number is less than 2^32 so we traverse for bit 0 to 31
int x = 1 << j; // traversing in bits
if (a & x) // if this bit is one so we make the prefix count as prevcount + 1
prefix[i][j] = 1 + prefix[i - 1][j];
else
prefix[i][j] = prefix[i - 1][j];
}
}
}
int maximum_num(int l, int r){
int numberofbits = r - l + 1; // the number of elements in the range hence the number of bits
int X = MAX; // we take the max value such that all of it's bits are one
// Iterating over each bit
for (int i = 0; i < 31; i++){
int x = prefix[r][i] - prefix[l - 1][i]; // calculating the number of set bits in the given range
if (x >= numberofbits - x){ // is number of 1's is more than number of 0's
int currentbit = 1 << i; // we set the current bit to prefix for toggling that bit in x
X = X ^ currentbit; // we make toggle that bit from 1 to 0
}
}
}
int main(){
int n = 5, q = 3; // number of element in our array and number of queries present
int A[] = { 210, 11, 48, 22, 133 }; // elements in our array
int L[] = { 1, 4, 2 }, R[] = { 3, 14, 4 }; // given queries
prefix_bit(A, n); // creating prefix bit array
for (int i = 0; i < q; i++)
cout << maximum_num(L[i], R[i]) << "\n";
return 0;
}

Output

2147483629
2147483647
2147483629

Explanation of the Above Code

In this approach, we first calculate the prefix count of 1’s present for each bit. Now when we get this count, we have solved our biggest problem that was traversing the queries. As of now, we are not going to traverse through each range. So we can calculate that through our prefix array now. Our main logic is that we calculate the number of resets and set bits in the range when we encounter a position where the set bit number is more than the number of reset bits. Hence, we reset that bit in our x now as we have initialized x with 2^31 - 1 so all of its bits will be set, and we find our answer by toggling the bits in x.

Conclusion

In this tutorial, we solve a problem to find the number whose sum of XOR with a given array range is maximum. We also learned the C++ program for this problem and the complete approach (Normal) by which we solved this problem. We can write the same program in other languages such as C, java, python, and other languages. We hope you find this tutorial helpful.