Пожалуйста, подпишитесь на официальный канал Codeforces в Telegram по ссылке https://t.me/codeforces_official. ×

Блог пользователя alt_438

Автор alt_438, история, 2 года назад, По-английски

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

  • Проголосовать: нравится
  • +10
  • Проголосовать: не нравится

»
2 года назад, # |
Rev. 3   Проголосовать: нравится +6 Проголосовать: не нравится

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 and u for 1. Let's define count(x) as amount of numbers from the array that are lying in x's subtree. Then, if count(v) is less then possible amount of strings in it's subtree, it means that MEX is somewhere in v's subtree. Otherwise, it's in u'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.

0 ^ 0 = 0
0 ^ 1 = 1
1 ^ 0 = 1
1 ^ 1 = 0

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. Let N(x) be index of bit that relates to vertex b; Let x[i] be i-th bit of x. Then for each vertex v in trie we should check whether x[N(v) + 1] == 1. If it is so, we simply need to swap v'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 that a ^= b and a ^= c is equal to a ^= (b ^ c). That means that we can make a variable currXor = 0. When we receive a query of xoring the array with x, we simply do currXor ^= x. When we receive a MEX query, we will deal with it just as I explained above, but considering the x to xor with is equal to currXor.