![]() |
VOOZH | about |
You are given a number of queries Q and each query will be of the following types:
1 <= x, y <= 10^9 1 <= 10^5 <= Q The data structure begins with only a 0 in it. Example:
Input: (1 10), (1 13), (2 10), (1 9), (1 5), (2 6) Output: 7 15 Add 10 and 13 to stream. Find maximum XOR with 10, which is 7 Insert 9 and 5 Find maximum XOR with 6 which is 15.
A good way to solve this problem is to use a Trie. A prerequisite for this post is Trie Insert and Search. Each Trie Node will look following:
struct TrieNode
{
// We use binary and hence we
// need only 2 children
TrieNode* Children[2];
bool isLeaf;
};
Another thing to handle is that we have to pad the binary equivalent of each input number by a suitable number of zeros to the left before storing them. The maximum possible value of x or y is 10^9 and hence 32 bits will be sufficient. So how does this work? Assume we have to insert 3 and 7 into Trie. The Trie starts out with 0 and after these three insertions can be visualized like this: 👁 Image
For simplification, the padding has been done to store each number using 3 bits. Note that in binary: 3 is 011 7 is 111 Now if we have to insert 1 into our Trie, we can note that 1 is 001 and we already have path for 00. So we make a new node for the last set bit and after connecting, we get this: 👁 Image
Now if we have to take XOR with 5 which is 101, we note that for the leftmost bit (position 2), we can choose a 0 starting at the root and thus we go to the left. This is the position 2 and we add 2^2 to the answer. For position 1, we have a 0 in 5 and we see that we can choose a 1 from our current node. Thus we go right and add 2^1 to the answer. For position 0, we have a 1 in 5 and we see that we cannot choose a 0 from our current node, thus we go right. 👁 Image
The path taken for 5 is shown above. The answer is thus 2^2 + 2^1 = 6.
7 15
The space taken by the Trie is O(n*log(n)). Each query of type 1 takes O(log(n)) time. Each query of type 2 takes O(log(n)) time too. Here n is the largest query number. Follow up problem: What if we are given three queries instead of two? 1) add(x) This means add x into your data structure (duplicates are allowed). 2) maxXOR(y) This means print the maximum possible XOR of y with all the elements already stored in the data structure. 3) remove(z) This means remove one instance of z from the data structure. What changes in the Trie solution can achieve this?