C++ Queries on XOR of Greatest Odd Divisor of the Range

Given an array of N integers and Q queries of ranges. For each query, we need to return the XOR of the greatest odd divisor of each number in the range.

The greatest odd divisor is the greatest odd number which can divide number N, e.g . The greatest odd divisor of 6 is 3, for example.

Input: nums[ ] = { 3, 6, 7, 10 }, query[ ] = { { 0, 2 }, { 1, 3 } }
Output:
query1: 7
query2: 1

Explanation: greatest odd divisors of nums array are { 3, 3, 7, 5 }.
For query 1 we need to find the XOR of indexes 0, 1, and 2 which is 7, and for query2 we need to find XOR of indexes 1, 2, and 3 which is 1.

Approach to Find the Solution

Simple Approach

First, in the simple approach, we need to find the greatest odd divisors of all the array elements. Then according to the range of the query, we need to calculate the XOR of each element in the range and return.

Efficient Approach

An efficient way to solve this problem is to create a prefix XOR array prefix_XOR[] of the array containing the greatest odd divisor numbers instead of every time finding XOR of each number in the range and return prefix_XOR[R] - prefix_XOR[L-1].

Prefix xor array is the array in which each element contains xor of all the previous elements.

Example

#include <bits/stdc++.h>
using namespace std;
int main(){
int nums[] = { 3, 6, 7, 10 };
int n = sizeof(nums) / sizeof(nums[0]);
int prefix_XOR[n];
// creating an array
// containing Greatest odd divisor of each element.
for (int i = 0; i < n; i++) {
while (nums[i] % 2 != 1)
nums[i] /= 2;
prefix_XOR[i] = nums[i];
}
// changing prefix_XOR array to prefix xor array.
for (int i = 1; i < n; i++)
prefix_XOR[i] = prefix_XOR[i - 1] ^ prefix_XOR[i];
// query array to find result of these queries.
int query[2][2] = {{0, 2},{1, 3}};
int q = sizeof(query) / sizeof(query[0]);
// finding results of queries.
for(int i = 0;i<q;i++){
if (query[i][0] == 0)
cout<<  prefix_XOR[query[i][1]] << endl;
else{
int result = prefix_XOR[query[0][1]] ^ prefix_XOR[query[i][0] - 1];
cout <<  result << endl;
}
}
return 0;
}

Output

7
4

Explanation of the Above Code

• prefix_XOR array is created to store the greatest odd divisor of each element and then change this array into prefix XOR array.

• The greatest odd divisor is calculated by dividing it by two until it's modulo 2 gives 1.

• Prefix xor array is created by traversing through the array and doing bitwise XOR of the current element with the previous element.

• The result of a query is calculated by subtracting the right index of prefix_XOR[] array with (left - 1) index of prefix_XOR[] array.

Conclusion

In this tutorial, we discussed a problem where we need to find the XOR of the greatest odd divisor of each number in the range of the given array. We discussed an approach to solve this problem by finding the greatest odd divisor of each element and using the prefix xor array. We also discussed the C++ program for this problem which we can do with programming languages like C, Java, Python, etc. We hope you find this article helpful.