Editorial for WC '17 Contest 2 S3 - Battle of the Pelennor Fields
Submitting an official solution before solving the problem yourself is a bannable offence.
We can process the events one by one while maintaining information about the state of the battlefield in the form of two data structures. The first is a set  of points (integers) at which there are non-vulnerable orcs (note that the answer at any point is simply the size of 
). The second is a set 
 of disjoint intervals (pairs of integers) of points in range of archers. Note that the intervals in 
 are closed (inclusive of its endpoints). Pre-populating 
 with a pair of dummy intervals 
 and 
 can make the following implementation more convenient. We'll want to implement both of these sets with balanced binary trees (e.g. C++ 
std::set) to allow for efficient insertion, deletion, searching, and ordered iteration.
It's important that the intervals in  are kept disjoint, such that no point on the number line is contained in multiple of them. For example, if there are two intervals 
 and 
 such that the latter is contained within the former (with 
 and 
), then 
 should be removed completely. On the other hand, if they partially overlap with one another (with 
, 
, and 
), then they should be combined into a single interval 
.
Let's now consider how we can process the arrival of an orc at position . We'll need to check whether or not this orc is already vulnerable (contained within an interval in 
). This can be done in 
 time by searching for the interval 
 in 
 with the largest 
 value such that 
, and then checking whether 
. If not, then 
 should be inserted into 
, also in 
 time.
What remains is being able to process the arrival of an archer at position  and with a bow range of 
. This archer corresponds to an interval 
, where 
 and 
. If 
 is already contained within an interval in 
, then it can be completely disregarded. This can be checked in 
 time, very similarly to the above check for orcs.
Otherwise, the next step is to remove all orcs in  which are within 
. To do so, we can search for the smallest point 
 in 
 such that 
 (if any), and repeatedly erase it and iterate to the next larger point in 
 until it's either greater than 
 or the end of 
 is reached. This process doesn't necessarily take 
 time for any given archer, as 
 orcs might be removed all at once, but it does take what's known as 
 amortized time, as each of the 
 orcs will be removed at most once in total. The result is that this step will take a total of 
 time across all archers.
Finally, we need to update  according to the new interval. We should first iterate over existing intervals 
 in 
 which overlap with 
 to the left (such that 
 and 
). For each such interval, we can erase it from 
 while combining it into the new interval by setting 
. Similarly to the previous step, this process takes 
 amortized time per archer. The same approach should then be repeated for existing intervals overlapping 
 to the right, and then finally, the new combined interval 
 can be inserted into 
, satisfying the guarantee that it's disjoint from all other intervals still in 
.
The total complexity of the algorithm described above is .
Comments