You are given an array of size N. you are also given M queries with each query Qi having a number k. you can perform the following operation during each query: XOR each element of A with k. Now,the answer to the query is the mex of A.
let R be an array of size M.the with element in R must be the answer to the ith query. your task is to return R. Note:-> A returns to its original state after each query. Constraints:-> 1<=N<=10^5 1<=M<=10^5
Oh, I had this task on my lesson 3 or 4 months ago. It may sound strange, but in this task you have to use trie. A tough task, tbh.
First of all, we need to find MEX without xoring numbers using the trie. Do to it, we are gonna use DFS on trie. Trie will be built on numbers as binary strings (all the strings will have a size of 31). Let's say, the DFS is at some vertex and it's children are
v
for 0 andu
for 1. Let's definecount(x)
as amount of numbers from the array that are lying inx
's subtree. Then, ifcount(v)
is less then possible amount of strings in it's subtree, it means that MEX is somewhere inv
's subtree. Otherwise, it's inu
's subtree.Ok, we now are able to find MEX without the changes using the trie. How are we gonna deal with the XOR queries? First of all, let's look at logical XOR.
We can interprete it as following: if we xor a logical value with a 1, it becomes the opposite value. Otherwise, it doesn't change. What does that mean to a trie? Well, let
x
be the value we are xoring the array with. Then let's look at all the vertexes in trie. LetN(x)
be index of bit that relates to vertexb
; Letx[i]
bei
-th bit ofx
. Then for each vertexv
in trie we should check whetherx[N(v) + 1] == 1
. If it is so, we simply need to swapv
's children (and their subtrees). It can be done by swapping their pointers, btw. But it still works in O(N) on XOR query, which is too slow.To make our solution faster, we need to notice that we don't actually need to swap it at all. We can simply check whether children need to be swapped while calculating the XOR. If so, we will firstly try to go in the 1-subtree. And if it's full, we'll go to the 0-subtree.
The last thing we need to do is to find out how to deal not with one xor query, but with many of those. Well, associativity of xor says that
a ^ (b ^ c) == (a ^ b) ^ c
. That means thata ^= b
anda ^= c
is equal toa ^= (b ^ c)
. That means that we can make a variablecurrXor = 0
. When we receive a query of xoring the array withx
, we simply docurrXor ^= x
. When we receive a MEX query, we will deal with it just as I explained above, but considering thex
to xor with is equal tocurrXor
.Oh, the last part of the solution is useless. I just saw that array returns to it's original state after every query.
Thanks a lot for amazing explanation,
:)