Editorial for Balkan OI '11 P3 - Medians
Submitting an official solution before solving the problem yourself is a bannable offence.
The algorithm presented below assumes that there exists a solution. Checking if a solution actually exists can be added pretty easily to the algorithm.
We will construct the permutation  incrementally, in a greedy
manner. Let 
 and 
 be two variables, initially set to 
 and 
. Let used be a
binary array with 
 elements, which is all set to 
, except for 
 and
, which are set to 
.
The function updateVmin() proceeds as follows: as long as , it
increments 
. The function 
updateVmax() proceeds as follows: as long as
, it decrements 
.
The overall algorithm proceeds as follows. First, we have  (and then
we set 
). Then:
for i=2 to N do {
    if (B[i] is equal to B[i-1]) then {
        // add to the permutation the smallest and the largest unused elements.
        updateVmin()
        A[2*i-2]=vmin; used[vmin]=1
        updateVmax()
        A[2*i-1]=vmax; used[vmax]=1
    }
    if (B[i]>B[i-1]) {
        if (used[B[i]] is equal to 0) {
            // B[i] has not been added to the permutation, yet.
            // Add B[i] to the permutation and the largest unused element.
            A[2*i-2]=B[i]; used[B[i]]=1
            updateVmax()
            A[2*i-1]=vmax; used[vmax]=1
        } else {
            // B[i] already exists in the permutation.
            // Add the largest two unused elements.
            updateVmax()
            A[2*i-2]=vmax; used[vmax]=1
            updateVmax()
            A[2*i-1]=vmax; used[vmax]=1
        }
    }
    if (B[i]<B[i-1]) {
        if (used[B[i]] is equal to 0) {
            // B[i] has not been added to the permutation, yet.
            // Add B[i] to the permutation and the smallest unused element.
            A[2*i-2]=B[i]; used[B[i]]=1
            updateVmin()
            A[2*i-1]=vmin; used[vmin]=1
        } else {
            // B[i] already exists in the permutation.
            // Add the smallest two unused elements.
            updateVmin()
            A[2*i-2]=vmin; used[vmin]=1
            updateVmin()
            A[2*i-1]=vmin; used[vmin]=1
        }
    }
}
The time complexity of the algorithm is .
Proof of correctness:
We first define  and 
. Note that, when a solution
exists, we always have 
 and 
 (that means none of the numbers
, or 
 can be the 
 median or any median after the 
). We will
prove that whenever we add 
 to the permutation, we have 
 and
whenever we add 
 to the permutation, we have 
. If that is the case,
then it is obvious that our algorithm finds a correct solution. That's because adding 
or 
 to the permutation will not interfere in any way with the values of the medians
after the current index 
.
A solution does not exist when  does not obey the inequalities regarding
 and 
 or when 
 and 
 are not adjacent in the sorted order of all
the first 
 elements of the permutation. Note that, if our claim regarding 
 and
 is true, then our algorithm cannot cause any of the previous conditions to occur
(unless the 
 values do not allow for any solution).
We will consider several cases (for ). We will always assume that we
have 
 (otherwise, we know from the start that there is no
solution).
Case 1: 
We need to add  and 
 to the permutation.
Let's assume that all the numbers  are already in the permutation
before considering the 
 median (and thus, we will have 
). In this case, the
median 
 of the first 
 elements of the permutation must be exactly 
(because there would be exactly 
 elements smaller than it in the permutation).
However, 
 cannot be equal to 
, because 
. Thus, we cannot have
. This contradicts our initial assumptions, leading us to the conclusion that at
least one of the numbers 
 was not used among the first 
 elements
of the permutation. 
 will be equal to one of the numbers not used which are at most
equal to 
 and, thus, we will have 
.
The proof is similar for  (actually, it is symmetrical).
Case 2: 
Subcase 2.1:  does not appear as a median before the index 
.
We assume our claim to be correct for the first  medians and we will prove it to
be correct for the first 
 medians. This means that neither 
 or 
 were ever equal to
. Thus, 
 does not exist in the permutation so far and we can add it. As for 
(which must also be added to the permutation), we will show that 
.
As before, let's assume that all the numbers  occur among the first
 elements of the permutation. But then we must have 
. And, since
, we would have 
 (but this contradicts our initial assumption!).
Subcase 2.2:  appeared as a median at some previous index (possibly more than
once).
As in the previous subcase, we assume that our claim is correct for the first 
medians and then we will prove that it is also correct for the first 
 medians.
We will need to add  to the permutation two times. Thus, we have to prove
that at least two elements among the set 
 have not been used, yet. Let's
assume first that all the elements 
 were used among the first 
elements of the permutation. This case is handled as in the previous subcase (the obtained
contradiction is, again, that 
).
Let's assume now that all the elements  have been used among the
first 
 elements of the permutation, except one (whose value we denote by 
). In
this case, we have 
. Since 
 appeared before as a median, it must a
value adjacent to 
 (in the sorted order of all the first 
 elements of the
permutation). Note how the value just before 
 in the sorted order is exactly
 (because 
 is the 
 elements in the sorted order). Thus, we obtain
. But this contradicts our general assumption that 
.
Case 3: .
This case is handled similarly to Case 2, but in a symmetrical manner (it also has two subcases).
Comments