Editorial for Riolku's Mock CCC S5 - Keen Keener Multiset
Submitting an official solution before solving the problem yourself is a bannable offence.
Author:
Subtask 1
This subtask was intended to reward brute force solutions.
Time Complexity:
Subtask 2
Maintaining a dynamic prefix-XOR array suffices.
Time Complexity:
Subtask 3
A trie can be augmented to support range XOR queries. To deal with type
Time Complexity:
Subtask 4
Here we present a SQRT decomposition solution on the values. Let
We'll focus on type
As the block size is a power of
However, we can show that the total number of merges is
- Initially, there will be at most
blocks with values - Each type
query can create at most non-empty block - Each type
query can create at most non-empty blocks. The proof is the following:- Non-empty blocks can only be created from values in partially covered blocks where the update is brute forced
- Obviously, the number of partially covered blocks is at most
- As the block size is a power of
, the top bits of the values that are XORed in each partially covered block will all be the same after being XORed. This means that they will all fall into the same new block
- Each merge removes one non-empty block
Time Complexity:
Comments
There's a simple
solution for subtask 4; it's essentially the same as the SQRT solution given, but stores trie nodes with lazy xor updates, and then merges trie nodes instead of blocks. In particular, to do operation 2:
The split step will create at most
new nodes, and each nontrivial step of the merge will delete one trie node, so the total runtime amortizes to 
.
We considered this pre-contest, but couldn't prove the runtime as easily. That said, this solution is very clean, and I love the split-merge lazy trie approach, so thanks for your comment.
Note: DMOJ uses
~
, not$
, for math, and you can use\mathcal
for nice time complexities.