978. Adding, Removing, Then the Best XOR
Run q operations against a MULTISET of values.
add v store one more copy of v
del v remove one copy of v; the problem guarantees a copy is stored
max x print the largest x XOR y over the stored values, or -1 if none
``` add 3, add 10, max 5, del 10, max 5, max 3 -> 15, 6, 0
max 7, add 7, max 7 -> -1, 0
add 5, add 5, del 5, max 5, del 5, max 5 -> 0, -1 ```
The first line is the point: with 3 and 10 stored, the best partner for 5 is 10, giving 15. Remove 10 and the answer drops to 6.
## Why removing a path is wrong
The insertion of problem 973 creates nodes along a 30 bit path. Deleting by removing those nodes destroys the paths of every other value that shares them: on a trie holding 3 and 10, deleting 10 would cut nodes that 3 is still using, since the two agree on their top bits.
It is also wrong for a multiset: two copies of 5 occupy one path, and deleting one copy must leave the other.
## A counter at every node
Give each node a counter of how many stored values pass through it. add
increments it along the path, del decrements it, and the query treats a child
with a counter of 0 as absent.
``` add / del v: node = root for b from 29 down to 0: create child (v >> b) & 1 if missing node = that child cnt[node] += 1 for add, -= 1 for del
max x: if nothing is stored: print -1 node = root, res = 0 for b from 29 down to 0: want = 1 - ((x >> b) & 1) if child[node][want] exists and cnt of it > 0: res |= 1 << b; node = that child else: node = child[node][1 - want] ```
## Why the counter test is exactly the right one
A node with counter 0 is on no stored value's path, so choosing it would lead to a walk with no value at the bottom. A node with a positive counter has at least one stored value below it, and since every stored value fills a whole 30 bit path, the walk can always continue. So "counter greater than 0" is precisely "this subtree still holds something", which is the condition the greedy needs.
Nodes are never physically removed, which is harmless: a counter of 0 makes them invisible, and reusing them costs nothing when the same value is added again.
## The empty case
max on an empty structure must print -1. The trie cannot report this by
itself once nodes have been created and abandoned, because the root still has
children with counters of 0. Keep a separate count of how many values are stored
and check it first.
## Against problem 973
973 builds the set once and then answers queries. Here the set changes between the queries, and the counter is what makes the same greedy walk survive deletions. Problem 985 uses exactly this structure to slide a window over sorted values.
## Overflow
Nothing here overflows. Values and answers are below 2^30 = 1073741824, and the
counters are at most q, which is 100000.
## Cost
Every operation is 30 steps. Space is at most 1 + 30 q = 3000001 nodes.
Constraints - `1 ≤ q ≤ 100000` - `0 ≤ every value ≤ 1073741823`, which is `2^30 - 1` - A `del v` is only given when at least one copy of `v` is currently stored. - At least one operation is a `max`.
Input
The first line contains one integer q.
Each of the next q lines is add v, del v or max v, where v is an
integer.
Output
For each max operation, in order, print one integer on its own line: the largest XOR of that value with any stored value, or -1 when nothing is stored.
Hints
Four rungs, in order. The last two open once you have submitted an attempt. A wrong one counts.