Editorial for EGOI '23 P1 - Inflation
Submitting an official solution before solving the problem yourself is a bannable offence.
Problem author: Pak Hei Chan.
Subtasks may not be ordered for ease of discussion.
The Problem
Given an array , support the following two types of operations
(there are
operations in total):
INFLATION x
: Addby
, for all
.
SET x y
: For all(
) such that
, set
.
After each operation output the sum of the array.
Subtask 2: Small
and 
Here, . To solve this subtask, one can simulate the process described
in the problem statement. Each of the two types of operations can be handled
in
time, by going through the array and changing the values appropriately.
Therefore, the overall complexity is
.
Since , C++ contestants do not have to worry about integer
overflow problems.
Expected score: 28.
Subtask 1: 
In this subtask, an solution works as well. Here difference from subtask 2
is that contestants are not required to have knowledge about arrays. Also, C++
contestants have to be careful about integer overflow problems in this subtask
(and all future subtasks): one need to use 64-bit integers (
long long
) to solve
this subtask.
Expected score: 14 for just subtask 1, 28 + 14 = 42 for subtask 1 and 2.
Subtask 3: Only INFLATION
In this subtask there are only INFLATION
events. Notice that an event of the
form INFLATION x
adds the sum of the array by . Therefore, one can simply
compute the sum of the array at first, then for every event
INFLATION x
, add
the sum of the array by . There is no need to add each element of the array
by
, and compute the sum of the array again.
Overall complexity: .
Expected score: 19.
Subtask 4: Only SET
In this subtask there are only SET
events. The key idea here is to try make our
computations constant time. Notice that the indices in the array do not matter,
what matters is the values.
Therefore, we will maintain a frequency array , where
counts
the number of items in the array
with value
.
Let the sum of the array before an operation be . After a
SET x y
event, the
following happens:
, update the sum of the array.
, all indices that have value
now have value
instead.
, there are no more indices that have value
now.
There is a special case where . In this case nothing happens. If one
simulates the above process it will not work. Careful handling is required to
pass this subtask.
Overall complexity: , where
is the maximum value in
the array.
Expected score: 23.
Full Task
To get the final 16 points, we merge the ideas of subtask 3 and subtask 4.
Consider maintaining a tag that keeps track of the total value added to
each element of the array. Initially,
.
That means, for each element, if its initial value is , its current value
must be equal to
.
This idea is important for understanding the following parts of the solution.
From subtask 4, we will maintain two things:
- Sum of the array
, ignoring global updates.
- Frequency array
. However, here the values can exceed the range
. Hence, we should use an
unordered_map
(in C++) or dictionary (in Python).
For an INFLATION x
operation:
- Add the
tag by
. There is no need to update
.
For a SET x y
operation:
- We want to set all elements that have value
to have value
instead.
- For an element that currently has value
, its initial value must have been
.
- These elements will then have a current value of
, which corresponds to an initial value of
.
- Look back at the key idea above if it doesn't make sense. If an
element has an initial value of
, its current value equals
, which matches the objective of the operation.
- Look back at the key idea above if it doesn't make sense. If an
element has an initial value of
- Based on the above two points, we subtract the inputs
and
by
.
- Perform the steps from subtask 4, if
:
Finally, the output after each operation is , since
does not take
into account of global updates.
Time complexity: \mathcal{O}(N+Q)\mathcal{O}(N + Q \log(N+Q))~ if a
map
is used instead
of unordered_map
in C++.
Expected score: 28 + 14 + 19 + 23 + 16 = 100.
Hard Version
The originally proposed version of this problem was more difficult (but solvable). For those who are interested, you may try thinking of the solution.
Given an array , support the following four types of operations/queries
(there are
operations in total):
- Given
,
, do
.
- Given
, do
for all
. (
INFLATION
) - Given
, output
.
- Given
and
, for all
(
) such that
, set
. (
SET
)
Solution to Hard Version
Consider grouping the initial array elements into equivalence classes, such that in each equivalence class, all elements have equal value. The idea is to use four maps/arrays:
- Value → equivalence class
- Equivalence class → value
- Equivalence class → set of indices
- Index in array → equivalence class
By maintaining these four maps/arrays for every type of operation, it can be
easily seen that all types of operations can be solved. The tricky part is in
the SET
operations, the essential thing that has to be done is to merge two
equivalence classes. We can naively insert all elements from the smaller set to
the larger set, then clear the smaller set. This technique is known as
small-to-large merging, and it ensures the total number of insert operations is
.
Comments