Event Sort
Overview
A set of half-open intervals is given. Each interval has an associated value . These intervals may overlap.
The following query is given: Find the minimum (or maximum) of defined at position .
Approach
Let's consider the example from ABC128-E.

The diagram looks like this, and we need to find the minimum value for each query. Now, consider a collection for the values . We treat the left endpoint as an insertion of into , and the right endpoint as a deletion of from . Queries are processed as query events.
This gives us the following events:
- Insertion event
- Deletion event
- Query event
We process these events in order of position. Insertion and deletion events can be in any order, but query events must be processed after all insertions and deletions at the same position have been handled.
Processing the ABC128 example yields the following:

With this approach, the values within range at position are exactly those in the collection . So for a query event, the minimum of collection is the answer at that position. By maintaining an Index, we can directly write the minimum value into the answer array.
In the example above, the same value was never inserted into multiple times, but in practice, multiple insertions of the same value can occur. Therefore, the data structure used for collection needs to be a multiset.
Implementation in Rust
multiset
Rust doesn't have a multiset, so we need to implement one ourselves.
Using a BTreeMap, we can relatively easily implement an ordered multiset-like structure. The key holds the value we want to treat as a set element, and the value holds the count. When the count reaches 0, we remove the key.
PartialOrd for enums
It would be nice to define Action as an enum. When you derive PartialOrd for a Rust enum, variants are compared in top-to-bottom order.