Editorial for LCC '21 Contest 4 S4 - Art Restoration
Submitting an official solution before solving the problem yourself is a bannable offence.
Author:
Subtask 1
Brute force all possible arrays and check if it satisfies all of the queries.
Time Complexity:
Subtask 2
The intended solution is Gaussian elimination, where every query can be treated as a equation with unknowns that sum up to . To simplify things, set the pivot at any index to be the smallest subarray beginning at index . This allows for all entries in the matrix (other than the last column) to either be 1 or 0.
Time Complexity:
Subtask 3
A similar technique to Gaussian elimination will be used but with optimizations due to all equations being comprised of contiguous sequences of 1
s. For every left index , have an ordered set storing the right index and sum of all subarrays that begin at index .
Iterate from left to right: if there is more than one subarray at any given index, take the subarray with the lowest right value and subtract it from all the other subarrays. For example, if we were at index and had the following subarrays:
[2, 4) = 6
[2, 5) = 8
[2, 6) = 4
We would end up with [4, 5) = 2
and [4, 6) = -2
. Note that this process always creates new subarrays that begin at the exact same index - the right value of the smallest subarray.
Keep the [2, 4)
subarray at index and take the remaining subarrays and push them to index , as we now have two subarrays that begin at index and end at indexes and . Repeat this process and you should end up with subarrays (new queries) entirely consisting with a unique -value. This is called row echelon form.
Perform back-substitution:
- Initialize an array
ans[]
. Initially set everything to . - Iterate from all indexes from to . Take the subarray beginning at , and let be the left index of the subarray, be the right index and be the sum. Take the sum of all elements in
ans[]
from to . Set to . Repeat. - Print out all values in
ans[]
.
Time Complexity: or
Subtask 4
A similar idea to Subtask 3 will be used. Since all subarrays consist of a unique -value anyways, back-substitution can immediately be used.
For back substitution, a data structure of your choice can be used to optimize taking the sum of all elements from to . Since all updates to ans
will be done in decreasing order of index (as index is the only update done, which we iterate from right to left), a suffix sum array will suffice.
Time Complexity:
Subtask 5
A similar idea to Subtask 3 will be used, but with a few key observations:
- Since we are simply storing the right index of all subarrays, subtracting the subarray with the smallest at any given from all other subarrays beginning at the same index is the same as removing a single element from the set at , and then taking the union of the set at with the set at .
- The union of two sets can be done by taking the smaller set and inserting all its elements into the larger. Since when iterating from left to right, all "finished" sets will never be reused, this can be done in . The sum of all union operations for all indexes will be at most . Proof of this is left as an exercise to the reader.
- To handle subtracting the sum of the lowest right value subarray to all other subarrays, a lazy value for all indexes representing a number to subtract from all subarrays beginning at can be stored. When merging sets, resolve the lazy value of the smaller set (manually add
lazy[i]
to all elements in the smaller set, setlazy[i]
to afterwards)
Alternatively, realize that the Subtask 3 solution is only in its worst case; if instead of taking the subarray with the lowest right value, one takes a random subarray to subtract from other subarrays, the average case becomes amortized . The proof of this is left as an exercise to the reader.
Time Complexity:
Comments