Editorial for COCI '07 Contest 3 #6 Redoks
Submitting an official solution before solving the problem yourself is a bannable offence.
If we keep the dials in a data structure, then to make the solution efficient enough, each update and query operation will have to run in sub-linear time.
One way to achieve this is to group adjacent dials into buckets containing about
By using a different data structure, we can reduce the time to
Imagine a binary tree in which every leaf represents one dial. Every node in the tree contains
Consider first how to perform a query in this tree. Given an interval
- If all dials in the subtree of the current node are contained in
, return the numbers contained in this node. - If the dials
are entirely contained in the left or right child of the current node, then move to that node (the other node is of no interest). - Otherwise (some of the dials
are in the left subtree, and some in the right subtree), recursively query both subtrees and add the results together.
This procedure really splits the query interval into subintervals whose lengths decrease exponentially, using as large subintervals as possible. The time complexity is
To keep the entire tree updated, the update operation would need to be linear, because for example, when Luka clicks all the dials, the entire tree would need to be updated.
To remedy this, we can use lazy propagation – when an update operation would update the entire subtree rooted at some node, don't actually do this, but instead increase a "laziness" counter in that node. When another update or query operation would visit one of the node's children, only then propagate the counter to the children.
Comments