Editorial for COCI '06 Contest 3 #6 Lista


Remember to use this editorial only when stuck, and not to copy-paste code from it. Please be respectful to the problem author and editorialist.
Submitting an official solution before solving the problem yourself is a bannable offence.

There are three parts to the solution.

The first part requires us to simulate Mirko's moves. As suggested by the problem statement, a doubly-linked list is to be used, supporting three operations ("erase", "insert before" and "insert after").

The second part requires us to find the smallest set of nodes to be moved to bring the list back to its starting state. Note that this is equivalent to finding the largest set of nodes that will not be moved, or the longest increasing subsequence (not necessarily contiguous). The longest increasing subsequence is found as follows.

Let M[d] be the smallest number that can end an increasing subsequence of length d. M is then a (not necessarily strictly) increasing sequence – if an increasing subsequence of length d+1 can end in x, then so can a subsequence of length d.

Let M[0] = 0 and M[d>0] = \infty to start with. Iterate the list left to right, and for each number x:

The number x can extend any subsequence ending in a number less than x. We use binary search to find the largest d so that M[d] < x. Appending x to that subsequence, the length becomes d+1, so we set M[d+1] = x.

The length of the longest increasing subsequence is the largest d for which M[d] is finite. The solution is then N-d.

In the third part we find the sequence of moves that restores the list's original state. Extract the numbers that form the longest increasing subsequence into a separate sequence A (sorted in increasing order). The following algorithm generates the desired sequence of moves:

for each number x from 1 to N not in A
  let y be the smallest number in A such that y > x
  if there is no such y then
    move x to the end of the list
  else
    move x in front of y

Comments

There are no comments at the moment.