Editorial for Bubble Cup V9 G Heroes of Making Magic III
Submitting an official solution before solving the problem yourself is a bannable offence.
For queries of type 2, we are only interested in the elements with
in the interval
, and nothing else. For the sake of convenience, label those elements as
, where
.
It can be easily seen that in order to clear a segment, we can just move back and forth between positions and
until
becomes
, move to
and alternate between
and
, etc – until we zero out the last element. If we want this procedure to succeed, several (in)equalities must hold:
(since we have to decrease the first element of the segment in the first step)
(after following this procedure,
is decreased exactly by
, and we end up on
)
, or,
, …
- In general,
has to be greater or equal to
, if
is odd, and
, if
is even
Equivalently, if we define a new sequence , such that
, and
, these inequalities are equivalent to stating that
and
.
Of course, we do not have to store the array for each pair of indices
, but it is enough to calculate it once, for the entire initial array
. Then, we can calculate the appropriate values of
for any interval
(
is the zero-based relative position of an element inside the segment): Let
. Then,
- For even values of
,
- For odd values of
,
Now we only need a way to maintain the array after updates of the form "
". Fortunately, we can see that this array is updated in a very regular way:
- Elements on even positions inside the interval
are increased by
- If
is even, elements on positions
are decreased by
, and elements on positions
are increased by
All of this can be derived from our definition of .
Both of these queries can be efficiently implemented using a lazy-propagation segment tree, where each internal node stores two numbers, the minimal of its odd- and even-indexed leaves.
Using the approach described above, we arrive at a solution with the complexity of .
Comments