#include <bits/stdc++.h>
using
namespace
std;
class
TrieNode {
public
:
TrieNode() {
nums[0] = nums[1] = nullptr;
prefixValue = 0;
}
TrieNode *nums[2];
int
prefixValue;
};
class
Solution {
public
:
void
maximizeXor(std::vector<
int
>& nums,
std::vector<std::pair<
int
,
int
>>& queries) {
int
queriesLength = queries.size();
std::vector<
int
> ans(queriesLength);
std::vector<std::vector<
int
>> temp(queriesLength, std::vector<
int
>(3));
for
(
int
i = 0; i < queriesLength; i++) {
temp[i][0] = queries[i].first;
temp[i][1] = queries[i].second;
temp[i][2] = i;
}
std::sort(temp.begin(), temp.end(),
[](
const
auto
& a,
const
auto
& b) {
return
a[1] < b[1]; });
int
index = 0;
std::sort(nums.begin(), nums.end());
TrieNode *root =
new
TrieNode();
for
(
const
auto
& query : temp) {
while
(index < nums.size() && nums[index] <= query[1]) {
insert(root, nums[index]);
index++;
}
int
tempAns = -1;
if
(index != 0) {
tempAns = search(root, query[0]);
}
ans[query[2]] = tempAns;
}
for
(
auto
num : ans) {
cout << num <<
" "
;
}
}
void
insert(TrieNode *root,
int
n) {
TrieNode *node = root;
for
(
int
i = 31; i >= 0; i--) {
int
bit = (n >> i) & 1;
if
(!node->nums[bit]) {
node->nums[bit] =
new
TrieNode();
}
node = node->nums[bit];
}
node->prefixValue = n;
}
int
search(TrieNode *root,
int
n) {
TrieNode *node = root;
for
(
int
i = 31; i >= 0; i--) {
int
bit = (n >> i) & 1;
int
requiredBit = bit == 1 ? 0 : 1;
if
(node->nums[requiredBit]) {
node = node->nums[requiredBit];
}
else
{
node = node->nums[bit];
}
}
return
node->prefixValue ^ n;
}
};
int
main() {
Solution sol;
std::vector<
int
> nums = {0, 1, 2, 3, 4};
std::vector<std::pair<
int
,
int
>> queries = {{3, 1}, {1, 3}, {5, 6}};
sol.maximizeXor(nums, queries);
}