Разбор
Problem Author: | Konstantin Denisov |
Prepared by: | Konstantin Denisov, Maxim Shvedchenko |
Written by: | Konstantin Denisov |
Group 1. Enumerate all possible sets and check if we can sort the permutation for each of the sets.
Group 2. The size of the minimum set when does not exceed (if we choose , it is not difficult to sort any permutation of size up to ), so we can only enumerate sets of size up to and check if we can sort the permutation.
Group 3. There are three possible cases depending on the minimum size of the good set in this case:
for all ;
and ;
Otherwise .
Using std::map
, we can maintain a set of all values and check how many unique non-zero values exist.
Group 4. Let us have some set , with which we can sort our permutation using the operations from the condition.
Consider the element that was at position in the initial permutation. Obviously, in the identity permutation, it is at position . Let's consider the sequence of positions that the element of the permutation with value visited before moving to its final position:
.
where , with for such that .
Let's express in terms of : . Then we have that
.
That is, in order to move the element with value to its position, it is necessary that the XORs of the elements of the set can represent the number for each : .
Recall the XOR basis. The XOR basis is the minimal set of numbers that can represent any number of a given set using XOR combinations. You can learn more here.
It can be proven that if we take as the XOR basis of the numbers constructed by the algorithm given below, then this will be one of the minimum size sets with which we can sort the given permutation.
vector <int> basis; void add (int x) { for (int i : basis) { x = min(x, x ^ i); } if (x) { for (int &i : basis) { i = min(i, i ^ x); } basis.push_back(x); } }
Then the answer to each query is the size of the XOR basis built on the numbers .
Thus, after each query, we can compute the size of the XOR basis in and output it. The complexity of the solution is .
Group 5. Using a segment tree, we can maintain the XOR basis of the array in per query. In each vertex, we will store the XOR basis of the numbers for which the corresponding segment of the segment tree is responsible.
Merging two bases can be done in place in . Thus, the update operation will work in .
Group 6. When , we know all queries in advance. We can add elements to the XOR basis. However, unfortunately, we cannot remove them. Given all this, we can use this technique, which allows us to delete from a structure where we can add if the queries are given in advance.
Group 7.
How to maintain the XOR basis online in per query can be learned from this link.