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 C++14 (GCC 5.4.1) (judge verdict: Wrong Answer)

#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
#include <algorithm>
#include <numeric>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <bitset>
#include <climits>
#define REP(i,n) for (int i=0;i<(n);i++)
#define FOR(i,a,b) for (int i=(a);i<(b);i++)
#define RREP(i,n) for (int i=(n)-1;i>=0;i--)
#define RFOR(i,a,b) for (int i=(a)-1;i>=(b);i--)
#define ll long long
#define ull unsigned long long
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};
const int INF = 1e9;
const int MOD = 1e9 + 7;

using namespace std;

const int MAX_N = 4*1e5 + 1;

pair<int,int> p_min(pair<int,int>& a, pair<int,int>& b){
  if(a.first < b.first) return a;
  else return b;
}

struct RMQ{
	int n;
	pair<int,int> dat[MAX_N*2 - 1];
  bool iseven;
	void init(int n_, bool is) {
		n = 1;
    iseven = is;
		while(n<n_)n*=2;//nが２のべき乗でないとupdateがバグる
		REP(i,2*n-1)dat[i] = {INT_MAX, i};
	}
	//インデックスiの値をxに変更
	void update(int i,int x){
		i += n-1;
		dat[i] = {x, i - n + 1};
		while(i > 0){
			i = (i-1)/2;
			dat[i] = p_min(dat[i*2+1],dat[i*2+2]);
		}
	}
	//[a,b)の最小値、ｌ、ｒにはノードｋに対応づく区間を与える
	//最初はquery(a,b,0,0,n)で呼び出し節点から始めて、潜ってくイメージ
  pair<int,int>query(int a,int b,int k,int l,int r){
    pair<int,int> res = query2(a,b,k,l,r);
    res.second = res.second*2 + iseven;
    return res;
  }
	pair<int,int>query2(int a,int b,int k,int l,int r){
		if(r <= a || b <= l)return {INT_MAX, -1};//交差しない
		if(a <= l && r <= b)return dat[k];//完全に含む
		else{
			pair<int,int> vl = query2(a,b,k*2+1,l,l+(r-l)/2);
			pair<int,int> vr = query2(a,b,k*2+2,l+(r-l)/2,r);
			return p_min(vl,vr);
		}
	}
};
struct Data{
  int l, r;
  pair<int, int> odd, even;//first is value, second is index
  bool iseven;
};
int main(){
  cin.tie(0);
  ios::sync_with_stdio(false);
  int N;
  cin >> N;
  RMQ rmq_even, rmq_odd;
  rmq_even.init(N/2, true);
  rmq_odd.init(N/2, false);
  REP(i,N){
    int p;
    cin >> p;
    if(i & 1)rmq_even.update(i / 2, p);
    else rmq_odd.update(i / 2, p);
  }
  auto c = [](Data& a, Data& b){
    return a.odd.first > b.odd.first;
  };
  priority_queue<Data, vector<Data>, decltype(c) > que(c);
  que.push({0,N,rmq_odd.query(0,N/2,0,0,N/2),rmq_even.query(0,N/2,0,0,N/2),false});
  int ans[MAX_N];
  int ans_i = 0;
  REP(i,N / 2){
    Data d = que.top();
    que.pop();
    if(d.l % 2 == 0){// 開始が奇数index
      que.push({d.l, d.odd.second, rmq_odd.query(d.l / 2, d.odd.second / 2 , 0, 0, N/2),rmq_even.query(d.l / 2, d.odd.second / 2 , 0, 0, N/2), d.iseven});//l
      que.push({d.odd.second + 1, d.even.second, rmq_even.query(d.odd.second / 2, d.even.second / 2, 0, 0, N/2), rmq_odd.query(d.odd.second / 2 + 1, d.even.second / 2 + 1, 0, 0, N/2),!d.iseven});//c
      que.push({d.even.second + 1, d.r, rmq_odd.query(d.even.second / 2 + 1, d.r / 2, 0, 0, N/2), rmq_even.query(d.even.second / 2 + 1, d.r / 2, 0, 0, N/2), d.iseven});//r
    }else{
      que.push({d.l, d.odd.second, rmq_even.query(d.l / 2, d.odd.second / 2 , 0, 0, N/2),rmq_odd.query(d.l / 2 + 1, d.odd.second / 2 , 0, 0, N/2), d.iseven});//l
      que.push({d.odd.second + 1, d.even.second, rmq_odd.query(d.odd.second / 2 + 1, d.even.second / 2, 0, 0, N/2), rmq_even.query(d.odd.second / 2 + 1, d.even.second / 2, 0, 0, N/2),!d.iseven});//c
      que.push({d.even.second + 1, d.r, rmq_even.query(d.even.second / 2, d.r / 2, 0, 0, N/2), rmq_odd.query(d.even.second / 2 + 1, d.r / 2, 0, 0, N/2), d.iseven});//r
    }
      
    ans[ans_i] = d.odd.first;
    ans[ans_i + 1] = d.even.first;
    ans_i += 2;
  }
  REP(i,N){
    if(i)cout << ' ';
    cout << ans[i];
  }
  cout << endl;
  return 0;
}