Maximum XOR Queries With an Element From Array
Last Updated :
18 Apr, 2025
Given an array arr[]
of size n
containing non-negative integers and also given a list of q
queries in a 2D array queries[][]
, where each query is of the form [x
i, m
i]
. For each query, you need to find the maximum value of (xi XOR arr[j])
such that arr[j]
is less than or equal to m
i.
In simple terms, you're looking for the number in arr
(that is not bigger than mi) which, when XOR with xi
, gives the highest possible result.
If no such number exists (i.e., all elements in arr
are greater than mi
), return -1
for that query.
Return an array, where ith index stores the result for the ith
query.
Examples
Input: arr[] = [0, 1, 2, 3, 4], queries[][] = [[3, 1], [1, 3], [5, 6]]
Output: [3, 3, 7]
Explanation:
- For the query [3, 1]:
Only elements in arr that are ≤ 1 are 0 and 1.
3 XOR 0 = 3 and 3 XOR 1 = 2.
So, the maximum result is 3. - For the query [1, 3]:
Elements ≤ 3 in arr are 0, 1, 2, 3
1 XOR 2 = 3 gives the highest value.
So, the maximum result is 3. - For the query [5, 6]:
All elements of arr are ≤ 6.
5 XOR 2 = 7 gives the highest value.
So, the maximum result is 7.
Input: arr[] = [5, 2, 4, 6, 6, 3], queries[][] = [[12, 4], [8, 1], [6, 3]]
Output: [15, -1, 5]
Explanation:
- For the query [12, 4]:
Elements in arr that are ≤ 4 are 2, 4, and 3.
Maximum result is 12 XOR 3 = 15. - For the query [8, 1]:
There is no element in arr that is ≤ 1.
So, the result is -1. - For the query [6, 3]:
Elements in arr that are ≤ 3 are 2 and 3.
Maximum result is 6 XOR 3 = 5.
[Naive Approach] Check All possible Combination - O(n*q) Time and O(1) Space
For each query, we loop through the array and verify if arr[i]
falls within the given limit. If it does, we calculate the XOR of arr[i]
and xi
, and continually update the maximum XOR value encountered throughout the iteration.
C++
#include <bits/stdc++.h>
using namespace std;
// Function to find the maximum XOR for each query
vector<int> maxXor(vector<int> &arr, vector<vector<int>> &queries){
// Number of elements in the array
int n = arr.size();
// Number of queries
int q = queries.size();
// Initialize the result vector with -1
vector<int> result(q, -1);
// Loop over each query
for (int i = 0; i < q; i++){
// Value to XOR with
int xi = queries[i][0];
// Maximum allowed value from arr
int mi = queries[i][1];
// Track the maximum XOR for this query
int maxXor = -1;
// Check all elements in arr
for (int j = 0; j < n; j++) {
// Only consider elements less than or equal to mi
if (arr[j] <= mi){
// Update maxXor if this XOR is greater than
// the current maximum
maxXor = max(maxXor, arr[j] ^ xi);
}
}
// Store the result for this query
result[i] = maxXor;
}
// Return results for all queries
return result;
}
int main(){
vector<int> arr = {0, 1, 2, 3, 4};
vector<vector<int>> queries = {{3, 1}, {1, 3}, {5, 6}};
vector<int> ans = maxXor(arr, queries);
// Output the results
for(auto it: ans){
cout << it << ' ';
}
return 0;
}
Java
import java.util.*;
class GfG {
// Function to find the maximum XOR for each query
static ArrayList<Integer> maxXor(int[] arr, int[][] queries) {
int n = arr.length;
int q = queries.length;
ArrayList<Integer> result = new ArrayList<>(Collections.nCopies(q, -1));
for (int i = 0; i < q; i++) {
// Value to XOR with
int xi = queries[i][0];
// Maximum allowed value from arr
int mi = queries[i][1];
int maxXor = -1;
for (int j = 0; j < n; j++) {
if (arr[j] <= mi) {
maxXor = Math.max(maxXor, arr[j] ^ xi);
}
}
result.set(i, maxXor);
}
return result;
}
public static void main(String[] args) {
int[] arr = {0, 1, 2, 3, 4};
int[][] queries = {{3, 1}, {1, 3}, {5, 6}};
ArrayList<Integer> ans = maxXor(arr, queries);
for (int x : ans) {
System.out.print(x + " ");
}
}
}
Python
def maxXor(arr, queries):
# Number of elements in the array
n = len(arr)
# Number of queries
q = len(queries)
# Initialize the result list with -1 (default for no valid elements)
result = [-1] * q
# Loop over each query
for i in range(q):
# Value to XOR with and max limit
xi, mi = queries[i]
maxXor = -1
# Check all elements in arr
for j in range(n):
if arr[j] <= mi:
maxXor = max(maxXor, arr[j] ^ xi)
# Store result
result[i] = maxXor
return result
if __name__ == "__main__":
arr = [0, 1, 2, 3, 4]
queries = [[3, 1], [1, 3], [5, 6]]
ans = maxXor(arr, queries)
# Print the results
print(*ans)
C#
using System;
using System.Collections.Generic;
class GfG{
// Function to find the maximum XOR for each query
static List<int> maxXor(int[] arr, int[,] queries){
int n = arr.Length;
int q = queries.GetLength(0);
List<int> result = new List<int>(new int[q]);
for (int i = 0; i < q; i++) result[i] = -1;
for (int i = 0; i < q; i++){
// Value to XOR with
int xi = queries[i, 0];
// Maximum allowed value from arr
int mi = queries[i, 1];
int maxXor = -1;
for (int j = 0; j < n; j++){
if (arr[j] <= mi){
maxXor = Math.Max(maxXor, arr[j] ^ xi);
}
}
result[i] = maxXor;
}
return result;
}
static void Main(){
int[] arr = {0, 1, 2, 3, 4};
int[,] queries = {{3, 1}, {1, 3}, {5, 6}};
List<int> ans = maxXor(arr, queries);
foreach (int x in ans){
Console.Write(x + " ");
}
}
}
JavaScript
function maxXor(arr, queries) {
const n = arr.length;
const q = queries.length;
// Initialize the result array with -1
const result = new Array(q).fill(-1);
// Loop through each query
for (let i = 0; i < q; i++) {
const [xi, mi] = queries[i];
let maxXor = -1;
// Check all elements in arr
for (let j = 0; j < n; j++) {
if (arr[j] <= mi) {
maxXor = Math.max(maxXor, arr[j] ^ xi);
}
}
result[i] = maxXor;
}
return result;
}
// Driver code
const arr = [0, 1, 2, 3, 4];
const queries = [[3, 1], [1, 3], [5, 6]];
const ans = maxXor(arr, queries);
// Output the results
console.log(...ans);
[Expected Approach] Using Trie - O(n*logn + q*logq) Time and O(n + q) Space
We use a Trie in this problem to efficiently store and search for array elements based on their binary representation. The Trie allows us to quickly compute the maximum XOR for a given query by traversing the bits of the numbers, which reduces the time complexity from O(n*q) to O(n*logn + q*logq). The Trie structure enables fast insertion and retrieval of elements, making it ideal for maximizing the XOR in O(32) time per query. This optimization is key for handling large inputs efficiently
First, we sort both the input array and the queries by their “maximum allowed” value mim_imi. Then we process the queries in ascending order of mim_imi, maintaining a single pointer into the sorted array:
- Incremental Trie–Building
As we move from one query to the next, we insert into the Trie all array elements ≤mi that haven’t yet been added. Each element is inserted exactly once, in O(32) bit‑steps. - Constant‑Time XOR Lookup
Once the Trie contains only those elements allowed by the current query, we compute max(arr[j] XOR xi)by a single 32‑bit traversal of the Trie, again in O(32).
C++
#include <bits/stdc++.h>
using namespace std;
// Trie Node class
class node {
public:
node *left;
node *right;
};
// Trie class to insert numbers and find maximum XOR
class trie {
node *root;
public:
// Constructor to initialize the root
trie() {
root = new node();
}
// Insert a number into the Trie (bit by bit from MSB to LSB)
void insert(int n) {
node *temp = root;
for (int i = 31; i >= 0; i--) {
int bit = (n >> i) & 1;
if (bit == 0) {
if (temp->left == NULL)
temp->left = new node();
temp = temp->left;
} else {
if (temp->right == NULL)
temp->right = new node();
temp = temp->right;
}
}
}
// Helper function to find the maximum XOR value with a given number
int xorHelper(int value) {
int curr = 0;
node *temp = root;
for (int j = 31; j >= 0; j--) {
int bit = (value >> j) & 1;
// Prefer the opposite bit for maximizing XOR
if (bit == 0) {
if (temp->right != NULL) {
temp = temp->right;
curr += (1 << j);
} else {
temp = temp->left;
}
} else {
if (temp->left != NULL) {
temp = temp->left;
curr += (1 << j);
} else {
temp = temp->right;
}
}
}
return curr;
}
};
// Function to answer all max XOR queries
vector<int> maxXor(vector<int> &arr, vector<vector<int>> &queries) {
int n = arr.size(), q = queries.size();
vector<int> ans(q); // Result array
vector<vector<int>> qry;
// Sort array for efficient traversal
sort(arr.begin(), arr.end());
// Transform queries: [mi, xi, index] for sorting by mi
for (int i = 0; i < q; i++) {
qry.push_back({queries[i][1], queries[i][0], i});
}
// Sort queries by mi (max value constraint)
sort(qry.begin(), qry.end());
int j = 0;
trie tree;
// Process each query in increasing order of mi
for (int i = 0; i < q; i++) {
// Insert all array elements <= mi into the Trie
while (j < arr.size() && arr[j] <= qry[i][0]) {
tree.insert(arr[j++]);
}
// If no elements <= mi, answer is -1
if (j == 0)
ans[qry[i][2]] = -1;
else
// Get max XOR with xi using Trie
ans[qry[i][2]] = tree.xorHelper(qry[i][1]);
}
return ans;
}
int main() {
vector<int> arr = {0, 1, 2, 3, 4};
// Sample queries: each query is {xi, mi}
vector<vector<int>> queries = {{3, 1}, {1, 3}, {5, 6}};
// Get answers for the queries
vector<int> ans = maxXor(arr, queries);
// Output the results
for (auto it : ans) {
cout << it << ' ';
}
return 0;
}
Java
import java.util.*;
class Node {
Node left, right;
}
class Trie {
Node root;
public Trie() {
root = new Node();
}
// Insert number into Trie
public void insert(int n) {
Node temp = root;
for (int i = 31; i >= 0; i--) {
int bit = (n >> i) & 1;
if (bit == 0) {
if (temp.left == null)
temp.left = new Node();
temp = temp.left;
} else {
if (temp.right == null)
temp.right = new Node();
temp = temp.right;
}
}
}
// Find max XOR with given value
public int xorHelper(int value) {
Node temp = root;
int curr = 0;
for (int j = 31; j >= 0; j--) {
int bit = (value >> j) & 1;
if (bit == 0) {
if (temp.right != null) {
temp = temp.right;
curr += (1 << j);
} else {
temp = temp.left;
}
} else {
if (temp.left != null) {
temp = temp.left;
curr += (1 << j);
} else {
temp = temp.right;
}
}
}
return curr;
}
}
class GfG {
static ArrayList<Integer> maxXor(int[] arr, int[][] queries) {
int n = arr.length, q = queries.length;
ArrayList<Integer> ans = new ArrayList<>(Collections.nCopies(q, 0));
ArrayList<int[]> qry = new ArrayList<>();
Arrays.sort(arr);
// Add [mi, xi, index] format for each query
for (int i = 0; i < q; i++) {
qry.add(new int[]{queries[i][1], queries[i][0], i});
}
// Sort queries by mi
qry.sort(Comparator.comparingInt(a -> a[0]));
Trie tree = new Trie();
int j = 0;
for (int i = 0; i < q; i++) {
int mi = qry.get(i)[0];
int xi = qry.get(i)[1];
int idx = qry.get(i)[2];
while (j < n && arr[j] <= mi) {
tree.insert(arr[j++]);
}
if (j == 0) {
ans.set(idx, -1);
} else {
ans.set(idx, tree.xorHelper(xi));
}
}
return ans;
}
public static void main(String[] args) {
int[] arr = {0, 1, 2, 3, 4};
int[][] queries = {{3, 1}, {1, 3}, {5, 6}};
ArrayList<Integer> ans = maxXor(arr, queries);
for (int val : ans) {
System.out.print(val + " ");
}
}
}
Python
# Trie Node class
class node:
def __init__(self):
# Represents bit 0
self.left = None
# Represents bit 1
self.right = None
# Trie class to insert numbers and find maximum XOR
class trie:
def __init__(self):
self.root = node()
# Insert a number into the Trie (bit by bit from MSB to LSB)
def insert(self, n):
temp = self.root
for i in range(31, -1, -1):
bit = (n >> i) & 1
if bit == 0:
if temp.left is None:
temp.left = node()
temp = temp.left
else:
if temp.right is None:
temp.right = node()
temp = temp.right
# Helper function to find the maximum XOR value with a given number
def xorHelper(self, value):
curr = 0
temp = self.root
for j in range(31, -1, -1):
bit = (value >> j) & 1
# Prefer the opposite bit for maximizing XOR
if bit == 0:
if temp.right is not None:
temp = temp.right
curr += (1 << j)
else:
temp = temp.left
else:
if temp.left is not None:
temp = temp.left
curr += (1 << j)
else:
temp = temp.right
return curr
# Function to answer all max XOR queries
def maxXor(arr, queries):
n = len(arr)
q = len(queries)
# Result array
ans = [-1] * q
qry = []
# Sort the array for efficient Trie population
arr.sort()
# Transform queries: [mi, xi, index] for sorting by mi
for i in range(q):
qry.append([queries[i][1], queries[i][0], i])
# Sort queries by mi (max value constraint)
qry.sort()
j = 0
tree = trie()
# Process each query in increasing order of mi
for i in range(q):
# Insert all array elements <= mi into the Trie
while j < len(arr) and arr[j] <= qry[i][0]:
tree.insert(arr[j])
j += 1
# If no elements <= mi, answer is -1
if j == 0:
ans[qry[i][2]] = -1
else:
# Get max XOR with xi using Trie
ans[qry[i][2]] = tree.xorHelper(qry[i][1])
return ans
if __name__ == "__main__":
arr = [0, 1, 2, 3, 4]
# Sample queries: each query is [xi, mi]
queries = [[3, 1], [1, 3], [5, 6]]
# Get answers for the queries
ans = maxXor(arr, queries)
# Output the results
print(*ans)
C#
using System;
using System.Collections.Generic;
class Node {
public Node Left;
public Node Right;
}
class Trie {
private Node root;
public Trie() {
root = new Node();
}
// Insert a number into the Trie (bit by bit from MSB to LSB)
public void Insert(int n) {
Node temp = root;
for (int i = 31; i >= 0; i--) {
int bit = (n >> i) & 1;
if (bit == 0) {
if (temp.Left == null)
temp.Left = new Node();
temp = temp.Left;
}
else {
if (temp.Right == null)
temp.Right = new Node();
temp = temp.Right;
}
}
}
// Helper function to find the maximum XOR value with a given number
public int XorHelper(int value) {
int curr = 0;
Node temp = root;
for (int j = 31; j >= 0; j--) {
int bit = (value >> j) & 1;
// Prefer the opposite bit for maximizing XOR
if (bit == 0) {
if (temp.Right != null) {
temp = temp.Right;
curr += (1 << j);
}
else {
temp = temp.Left;
}
}
else {
if (temp.Left != null) {
temp = temp.Left;
curr += (1 << j);
}
else {
temp = temp.Right;
}
}
}
return curr;
}
}
class GfG {
static List<int> maxXor(int[] arr, int[,] queries) {
int n = arr.Length, q = queries.GetLength(0);
List<int> ans = new List<int>(new int[q]);
List<List<int>> qry = new List<List<int>>();
// Sort the array for efficient Trie population
Array.Sort(arr);
// Transform queries: [mi, xi, index] for sorting by mi
for (int i = 0; i < q; i++) {
qry.Add(new List<int> { queries[i, 1], queries[i, 0], i });
}
// Sort queries by mi (max value constraint)
qry.Sort((a, b) => a[0].CompareTo(b[0]));
int j = 0;
Trie tree = new Trie();
// Process each query in increasing order of mi
for (int i = 0; i < q; i++) {
// Insert all array elements <= mi into the Trie
while (j < arr.Length && arr[j] <= qry[i][0]) {
tree.Insert(arr[j++]);
}
// If no elements <= mi, answer is -1
if (j == 0)
ans[qry[i][2]] = -1;
else
// Get max XOR with xi using Trie
ans[qry[i][2]] = tree.XorHelper(qry[i][1]);
}
return ans;
}
static void Main() {
int[] arr = { 0, 1, 2, 3, 4 };
// Sample queries: each query is [xi, mi]
int[,] queries = {
{ 3, 1 },
{ 1, 3 },
{ 5, 6 }
};
// Get answers for the queries
List<int> ans = maxXor(arr, queries);
// Output the results
foreach (var it in ans) {
Console.Write(it + " ");
}
}
}
JavaScript
class Node {
constructor() {
this.left = null;
this.right = null;
}
}
class Trie {
constructor() {
this.root = new Node();
}
// Insert a number into the Trie (bit by bit from MSB to LSB)
insert(n) {
let temp = this.root;
for (let i = 31; i >= 0; i--) {
let bit = (n >> i) & 1;
if (bit === 0) {
if (temp.left === null) {
temp.left = new Node();
}
temp = temp.left;
} else {
if (temp.right === null) {
temp.right = new Node();
}
temp = temp.right;
}
}
}
// Helper function to find the maximum XOR value with a given number
xorHelper(value) {
let curr = 0;
let temp = this.root;
for (let j = 31; j >= 0; j--) {
let bit = (value >> j) & 1;
// Prefer the opposite bit for maximizing XOR
if (bit === 0) {
if (temp.right !== null) {
temp = temp.right;
curr += (1 << j);
} else {
temp = temp.left;
}
} else {
if (temp.left !== null) {
temp = temp.left;
curr += (1 << j);
} else {
temp = temp.right;
}
}
}
return curr;
}
}
// Function to answer all max XOR queries
function maxXor(arr, queries) {
let n = arr.length, q = queries.length;
let ans = new Array(q); // Result array
let qry = [];
// Sort array for efficient traversal
arr.sort((a, b) => a - b);
// Transform queries: [mi, xi, index] for sorting by mi
for (let i = 0; i < q; i++) {
qry.push([queries[i][1], queries[i][0], i]);
}
// Sort queries by mi (max value constraint)
qry.sort((a, b) => a[0] - b[0]);
let j = 0;
let tree = new Trie();
// Process each query in increasing order of mi
for (let i = 0; i < q; i++) {
// Insert all array elements <= mi into the Trie
while (j < arr.length && arr[j] <= qry[i][0]) {
tree.insert(arr[j++]);
}
// If no elements <= mi, answer is -1
if (j === 0)
ans[qry[i][2]] = -1;
else
// Get max XOR with xi using Trie
ans[qry[i][2]] = tree.xorHelper(qry[i][1]);
}
return ans;
}
// Test the function with sample input
let arr = [0, 1, 2, 3, 4];
// Sample queries: each query is [xi, mi]
let queries = [
[3, 1],
[1, 3],
[5, 6]
];
// Get answers for the queries
let ans = maxXor(arr, queries);
// Output the results
console.log(ans.join(' '));
Similar Reads
Find element with the maximum set bits in an array
Given an array arr[]. The task is to find an element from arr[] which has the maximum count of set bits.Examples: Input: arr[] = {10, 100, 1000, 10000} Output: 1000 Binary(10) = 1010 (2 set bits) Binary(100) = 1100100 (3 set bits) Binary(1000) = 1111101000 (6 set bits) Binary(10000) = 10011100010000
5 min read
Maximum XOR of Two Numbers in an Array
Given an array arr[] of non-negative integers. The task is to find the maximum possible XOR of any two elements of the array. Example: Input: arr[] = [26, 100, 25, 13, 4, 14]Output: 126 Explanation: XOR of 26 ^ 100 = 126, which is the maximum possible XOR. Input: arr[] = [1, 2, 3, 4, 5, 6, 7]Output:
15 min read
Find all numbers that divide maximum array elements
Given an array of N numbers, the task is to print all the numbers greater than 1 which divides the maximum of array elements. Examples: Input: a[] = {6, 6, 12, 18, 13} Output: 2 3 6 All the numbers divide the maximum of array elements i.e., 4 Input: a[] = {12, 15, 27, 20, 40} Output: 2 3 4 5 Approac
7 min read
Maximum element in a sorted and rotated array
Given a sorted array arr[] (may contain duplicates) of size n that is rotated at some unknown point, the task is to find the maximum element in it. Examples: Input: arr[] = {5, 6, 1, 2, 3, 4}Output: 6Explanation: 6 is the maximum element present in the array. Input: arr[] = {3, 2, 2, 2}Output: 3Expl
7 min read
Remove all occurrences of any element for maximum array sum
Given an array of positive integers, remove all the occurrences of the element to get the maximum sum of the remaining array. Examples: Input : arr = {1, 1, 3} Output : 3 On removing 1 from the array, we get {3}. The total value is 3 Input : arr = {1, 1, 3, 3, 2, 2, 1, 1, 1} Output : 11 On removing
6 min read
Maximum possible XOR of every element in an array with another array
Two arrays A and B consisting of N elements are given. The task is to compute the maximum possible XOR of every element in array A with array B. Examples: Input : A : 7 3 9 12 B : 1 3 5 2 Output : 6 6 12 15 Explanation : 1 xor 7 = 6, 5 xor 3 = 6, 5 xor 9 = 12, 3 xor 12 = 15. A naive approach to solv
12 min read
Queries to calculate maximum Bitwise XOR of X with any array element not exceeding M
Given an array arr[] consisting of N non-negative integers and a 2D array queries[][] consisting of queries of the type {X, M}, the task for each query is to find the maximum Bitwise XOR of X with any array element whose value is at most M. If it is not possible to find the Bitwise XOR, then print "
15+ min read
Most frequent element in an array
Given an array, the task is to find the most frequent element in it. If there are multiple elements that appear a maximum number of times, return the maximum element. Examples: Input : arr[] = [1, 3, 2, 1, 4, 1]Output : 1Explanation: 1 appears three times in array which is maximum frequency. Input :
10 min read
Queries to find the maximum array element after removing elements from a given range
Given an array arr[] and an array Q[][] consisting of queries of the form of {L, R}, the task for each query is to find the maximum array element after removing array elements from the range of indices [L, R]. If the array becomes empty after removing the elements from given range of indices, then p
10 min read
Maximum OR of Two Numbers in an Array
Given an array Arr of non-negative integers of size N, the task is to find the maximum possible OR between two numbers present in the array. Example: Input: Arr = {25, 10, 2, 8, 5, 3}Output: 29 Input: Arr = {1, 2, 3, 4, 5, 6, 7}Output: 7 Naive Approach: A Simple Solution is to generate all pairs of
4 min read