Problem:
Score : 800 points

Problem Statement

Let N be a positive even number.

We have a permutation of (1, 2, ..., N), p = (p_1, p_2, ..., p_N).
Snuke is constructing another permutation of (1, 2, ..., N), q, following the procedure below.

First, let q be an empty sequence.
Then, perform the following operation until p becomes empty:

Select two adjacent elements in p, and call them x and y in order. Remove x and y from p (reducing the length of p by 2), and insert x and y, preserving the original order, at the beginning of q.

When p becomes empty, q will be a permutation of (1, 2, ..., N).

Find the lexicographically smallest permutation that can be obtained as q.

Constraints

N is an even number.

2 ≤ N ≤ 2 × 10^5

p is a permutation of (1, 2, ..., N).

Input

Input is given from Standard Input in the following format:

N
p_1 p_2 ... p_N

Output

Print the lexicographically smallest permutation, with spaces in between.

Sample Input 1

4
3 2 4 1

Sample Output 1

3 1 2 4

The solution above is obtained as follows:

p

q

(3, 2, 4, 1)

()

↓

↓

(3, 1)

(2, 4)

↓

↓

()

(3, 1, 2, 4)

Sample Input 2

2
1 2

Sample Output 2

1 2

Sample Input 3

8
4 6 3 2 8 5 7 1

Sample Output 3

3 1 2 7 4 6 8 5

The solution above is obtained as follows:

p

q

(4, 6, 3, 2, 8, 5, 7, 1)

()

↓

↓

(4, 6, 3, 2, 7, 1)

(8, 5)

↓

↓

(3, 2, 7, 1)

(4, 6, 8, 5)

↓

↓

(3, 1)

(2, 7, 4, 6, 8, 5)

↓

↓

()

(3, 1, 2, 7, 4, 6, 8, 5)

Solution in Ruby (2.3.3) (judge verdict: Time Limit Exceeded)

class SegTreeMin
    attr_reader :dat
    def initialize(n_input, top=Float::INFINITY)
        @n_input = n_input
        @n = 1 << @n_input.to_s(2).length
        @top = top
        @dat = Array.new(2 * @n - 1, @top)
    end

    def update(k, a)
        k += @n - 1
        @dat[k] = a
        while k > 0 do
            k = (k - 1) / 2
            #@dat[k] = [@dat[2*k+1], @dat[2*k+2]].min
            @dat[k] = @dat[2*k+1]
            @dat[k] = @dat[2*k+2] if @dat[k] > @dat[2*k+2]
        end
    end

    # This works only when inserting larger value than all existing values
    def update_larger(k, a)
        k += @n - 1
        @dat[k] = a
        while k > 0 do
            k = (k - 1) / 2
            if @dat[k] <= a
                break
            else
                @dat[k] = a
            end
        end
    end

    # include a and b
    def min_between(a, b)
        query(a, b + 1, 0, 0, @n)
    end

    def query(a, b, k, l, r)
        return @top if r <= a || b <= l
        return @dat[k] if a <= l && r <= b
        vl = query(a, b, k * 2 + 1, l, (l + r) / 2)
        vr = query(a, b, k * 2 + 2, (l + r) / 2, r)
        #return [vl, vr].min
        return vl < vr ? vl : vr
    end
end

class Heap
    attr_reader :size
    def initialize
        @heap = []
        @size = 0
    end

    def length
        @size
    end

    def push(x)
        i = @size
        @size += 1
        while i > 0 do
            p = (i - 1) / 2
            break if @heap[p] <= x
            @heap[i] = @heap[p]
            i = p
        end
        @heap[i] = x
        self
    end

    def pop
        return nil if @size == 0
        ret = @heap[0]
        @size -= 1
        x = @heap[@size]
        i = 0
        while i * 2 + 1 < @size do
            a = i * 2 + 1
            b = a + 1
            if b < @size && @heap[b] < @heap[a]
                a = b
            end
            break if @heap[a] >= x
            @heap[i] = @heap[a]
            i = a
        end
        @heap[i] = x
        @heap.pop
        return ret
    end
end

N = gets.to_i
ps = gets.split.map(&:to_i)

BIG = 2*N
st = []
st[0] = SegTreeMin.new(N/2, BIG)
st[1] = SegTreeMin.new(N/2, BIG)
pos = []
N.times do |i|
    pos[ps[i]] = i
end
(1..N).each do |num|
    st[pos[num]%2].update_larger(pos[num]/2, num)
end

min = st[0].min_between(0, (N-1)/2)
heap = Heap.new
heap.push(min)
range_l, range_r = Array.new(N+1), Array.new(N+1)
range_l[min] = 0
range_r[min] = N - 1

ans = []
(N/2).times do |i|
    left = heap.pop
    in_l = pos[left]
    out_l = range_l[left]
    out_r = range_r[left]
    right = st[out_r%2].min_between((in_l+1)/2, out_r/2)
    in_r = pos[right]
    ans.push(left)
    ans.push(right)
    if out_l < in_l
        min = st[out_l%2].min_between(out_l/2, in_l/2-1)
        heap.push(min)
        range_l[min] = out_l
        range_r[min] = in_l - 1
    end
    if in_l < in_r - 1
        min = st[(in_l+1)%2].min_between((in_l+1)/2, in_r/2-1)
        heap.push(min)
        range_l[min] = in_l + 1
        range_r[min] = in_r - 1
    end
    if in_r < out_r
        min = st[(in_r+1)%2].min_between((in_r+1)/2, (out_r-1)/2)
        heap.push(min)
        range_l[min] = in_r + 1
        range_r[min] = out_r
    end
end
puts ans.join(' ')