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 (Python):
import sys
input = sys.stdin.buffer.readline



class SparseTable():
    def __init__(self, N, A):
        self.N = N
        self.logN = N.bit_length()
        self.A = A
        self.table = [[i for i in range(N)]]
        for k in range(self.logN):
            tab = []
            for i in range(self.N-(1<<(k+1))+1):
                ind1 = self.table[-1][i]
                ind2 = self.table[-1][i+(1<<k)]
                if self.A[ind1] <= self.A[ind2]:
                    tab.append(ind1)
                else:
                    tab.append(ind2)
            self.table.append(tab)
    
    
    def query_min(self, l, r):
        k = (r-l).bit_length()-1
        indl = self.table[k][l]
        indr = self.table[k][r-(1<<k)]
        if self.A[indl] <= self.A[indr]:
            return self.A[indl], indl
        return self.A[indr], indr

import heapq as hp
N = int(input())
A = list(map(int, input().split()))

def main():
    SP1 = SparseTable((N+1)//2, A[::2])
    SP2 = SparseTable(N//2, A[1::2])

    ans = []
    q = []
    v, k = SP1.query_min(0, N//2)
    dic = {}
    dic[v] = (k, 0, N//2, True)
    hp.heappush(q, v)
    for _ in range(N//2):
        valuea = hp.heappop(q)
        ka, l, r, is1 = dic[valuea]
        ans.append(str(valuea))
        if is1:
            valueb, kb = SP2.query_min(ka, r)
            if ka < kb:
                m2, nk2 = SP2.query_min(ka, kb)
                hp.heappush(q, m2)
                dic[m2] = (nk2, ka, kb+1, False)
            if l < ka:
                m1, nk1 = SP1.query_min(l, ka)
                hp.heappush(q, m1)
                dic[m1] = (nk1, l, ka, True)
            if kb+1 < r:
                m3, nk3 = SP1.query_min(kb+1, r)
                hp.heappush(q, m3)
                dic[m3] = (nk3, kb+1, r, True)
        else:
            valueb, kb = SP1.query_min(ka+1, r)
            if ka+1 < kb:
                m1, nk1 = SP1.query_min(ka+1, kb)
                hp.heappush(q, m1)
                dic[m1] = (nk1, ka+1, kb, True)
            if l < ka:
                m2, nk2 = SP2.query_min(l, ka)
                hp.heappush(q, m2)
                dic[m2] = (nk2, l, ka+1, False)
            if kb < r-1:
                m3, nk3 = SP2.query_min(kb, r-1)
                hp.heappush(q, m3)
                dic[m3] = (nk3, kb, r, False)

        ans.append(str(valueb))

    print(" ".join(ans))


if __name__ == "__main__":
    main()

Solution (Python):
import sys
input = sys.stdin.readline



class SparseTable():
    def __init__(self, N, A):
        self.N = N
        self.logN = N.bit_length()
        self.A = A
        self.table = [[i for i in range(N)]]
        for k in range(self.logN):
            tab = []
            for i in range(self.N-(1<<(k+1))+1):
                ind1 = self.table[-1][i]
                ind2 = self.table[-1][i+(1<<k)]
                if self.A[ind1] <= self.A[ind2]:
                    tab.append(ind1)
                else:
                    tab.append(ind2)
            self.table.append(tab)
    
    
    def query_min(self, l, r):
        k = (r-l).bit_length()-1
        indl = self.table[k][l]
        indr = self.table[k][r-(1<<k)]
        if self.A[indl] <= self.A[indr]:
            return self.A[indl], indl
        return self.A[indr], indr

import heapq as hp
N = int(input())
A = list(map(int, input().split()))

def main():
    SP1 = SparseTable((N+1)//2, A[::2])
    SP2 = SparseTable(N//2, A[1::2])

    ans = []
    q = []
    v, k = SP1.query_min(0, N//2)
    dic = {}
    dic[v] = (k, 0, N//2, True)
    hp.heappush(q, v)
    for _ in range(N//2):
        valuea = hp.heappop(q)
        ka, l, r, is1 = dic[valuea]
        ans.append(str(valuea))
        if is1:
            valueb, kb = SP2.query_min(ka, r)
            if ka < kb:
                m2, nk2 = SP2.query_min(ka, kb)
                hp.heappush(q, m2)
                dic[m2] = (nk2, ka, kb+1, False)
            if l < ka:
                m1, nk1 = SP1.query_min(l, ka)
                hp.heappush(q, m1)
                dic[m1] = (nk1, l, ka, True)
            if kb+1 < r:
                m3, nk3 = SP1.query_min(kb+1, r)
                hp.heappush(q, m3)
                dic[m3] = (nk3, kb+1, r, True)
        else:
            valueb, kb = SP1.query_min(ka+1, r)
            if ka+1 < kb:
                m1, nk1 = SP1.query_min(ka+1, kb)
                hp.heappush(q, m1)
                dic[m1] = (nk1, ka+1, kb, True)
            if l < ka:
                m2, nk2 = SP2.query_min(l, ka)
                hp.heappush(q, m2)
                dic[m2] = (nk2, l, ka+1, False)
            if kb < r-1:
                m3, nk3 = SP2.query_min(kb, r-1)
                hp.heappush(q, m3)
                dic[m3] = (nk3, kb, r, False)

        ans.append(str(valueb))

    print(" ".join(ans))


if __name__ == "__main__":
    main()

Solution (Python):
def main():
    import sys
    from heapq import heappush, heappop
    input = sys.stdin.buffer.readline

    
    def STfunc(a, b):
        if a < b:
            return a
        else:
            return b

    
    class SparseTable():
        def __init__(self, A):
            
            self.N = len(A)
            self.K = self.N.bit_length() - 1
            self.table = [[0] * (self.K + 1) for _ in range(self.N)]
            for i, a in enumerate(A):
                self.table[i][0] = A[i]
            for k in range(1, self.K + 1):
                for i in range(self.N):
                    j = i + (1 << (k - 1))
                    if j <= self.N - 1:
                        self.table[i][k] = STfunc(self.table[i][k - 1], self.table[j][k - 1])
                    else:
                        self.table[i][k] = self.table[i][k - 1]

        def query(self, l, r):
            
            k = (r - l).bit_length() - 1
            return STfunc(self.table[l][k], self.table[r - (1 << k)][k])

    N = int(input())
    n = N//2
    A = list(map(int, input().split()))

    A_even = A[0:N:2]
    A_odd = A[1:N:2]
    ST_even = SparseTable(A_even)
    ST_odd = SparseTable(A_odd)
    val2idx = [0] * (N+1)
    for i in range(N):
        val2idx[A[i]] = i

    ans = []
    ans_append = ans.append
    pq = [(ST_even.query(0, n), 0, N)]
    for t in range(n):
        v1, left, right = heappop(pq)
        ans_append(v1)
        i = val2idx[v1]
        if i & 1:
            v2 = ST_even.query((i+1)//2, right//2 + 1)
            ans_append(v2)
            j = val2idx[v2]
            if left != i:
                heappush(pq, (ST_odd.query(left//2, i//2), left, i))
            if j-i > 1:
                heappush(pq, (ST_even.query((i+1)//2, j//2), i+1, j))
            if j+1 != right:
                heappush(pq, (ST_odd.query((j+1)//2, right//2), j+1, right))
        else:
            v2 = ST_odd.query(i//2, right//2)
            ans_append(v2)
            j = val2idx[v2]
            if left != i:
                heappush(pq, (ST_even.query(left//2, i//2), left, i))
            if j-i > 1:
                heappush(pq, (ST_odd.query((i+1)//2, j//2), i+1, j))
            if j+1 != right:
                heappush(pq, (ST_even.query((j+1)//2, right//2), j+1, right))

    print(*ans)


if __name__ == '__main__':
    main()

Solution (Python):
from collections import deque
import heapq
import sys
input = sys.stdin.readline


class SparseTable():
    """区間取得クエリをO(1)で答えるデータ構造をO(NlogN)で構築する
    query(l, r): 区間[l, r)に対するクエリに答える
    """
    def __init__(self, array, n):
        n = len(array)
        self.row_size = n.bit_length()

        
        
        self.log_table = [0] * (n + 1)
        for i in range(2, n + 1):
            self.log_table[i] = self.log_table[i//2] + 1

        
        self.sparse_table = [[0] * n for _ in range(self.row_size)]
        for i in range(n):
            self.sparse_table[0][i] = array[i]
        for row in range(1, self.row_size):
            for i in range(n - (1 << row) + 1):
                self.sparse_table[row][i] = self._merge(self.sparse_table[row - 1][i], \
                                            self.sparse_table[row - 1][i + (1 << row - 1)])

    def _merge(self, num1, num2):
        """クエリの内容"""
        return min(num1, num2)

    def query(self, l, r):
        """区間[l, r)に対するクエリに答える"""
        row = self.log_table[r - l]
        return self._merge(self.sparse_table[row][l], self.sparse_table[row][r - (1 << row)])


n = int(input())
p = list(map(int, input().split()))

q = [[0] * (n // 2) for i in range(2)]

for i in range(n):
    q[i%2][i//2] = p[i]

ind = {}
for i in range(n):
    ind[p[i]] = i

sp0 = SparseTable(q[0], n // 2)
sp1 = SparseTable(q[1], n // 2)

con = {}
ans = {}
div = 10**6
def solve(l, r):
    q = deque([l * div + r])
    while q:
        pos = q.pop()
        l, r = pos // div, pos % div 
        
        if l % 2 == 0:
            min1 = sp0.query(l//2, r//2)
        else:
            min1 = sp1.query(l//2, r//2)
        use_pos1 = ind[min1]
        
        
        if (l + 1) % 2 == 0:
            min2 = sp0.query((use_pos1 + 1) // 2, (r + 1) // 2)
        else:
            min2 = sp1.query((use_pos1 + 1) // 2, (r + 1) // 2)
        use_pos2 =  ind[min2]
        
        ans[pos] = min1 * div + min2
        con[pos] = []
        if l != use_pos1:
            con[pos].append(l * div + use_pos1)
            q.append(l * div + use_pos1)
        if use_pos1 + 1 != use_pos2:
            con[pos].append((use_pos1 + 1) * div + use_pos2)
            q.append((use_pos1 + 1) * div + use_pos2)
        if use_pos2 + 1 != r:
            con[pos].append((use_pos2 + 1) * div + r)
            q.append((use_pos2 + 1) * div + r)

    return


solve(0, n)
res = []
q = [(ans[n], n)]
while q:
    num, i = heapq.heappop(q)
    min1, min2 = num // div, num % div
    res.append(min1)
    res.append(min2)
    for new_num in con[i]:
        heapq.heappush(q, (ans[new_num], new_num))
print(*res)

Solution (Python):
from collections import defaultdict, deque, Counter
from heapq import heappush, heappop, heapify
import math
import bisect
import random
from itertools import permutations, accumulate, combinations, product
import sys
from pprint import pprint
from copy import deepcopy
import string
from bisect import bisect_left, bisect_right
from math import factorial, ceil, floor
from operator import mul
from functools import reduce
from pprint import pprint


sys.setrecursionlimit(2147483647)
INF = 1 << 32
def LI(): return list(map(int, sys.stdin.buffer.readline().split()))
def I(): return int(sys.stdin.buffer.readline())
def LS(): return sys.stdin.buffer.readline().rstrip().decode('utf-8').split()
def S(): return sys.stdin.buffer.readline().rstrip().decode('utf-8')
def IR(n): return [I() for i in range(n)]
def LIR(n): return [LI() for i in range(n)]
def SR(n): return [S() for i in range(n)]
def LSR(n): return [LS() for i in range(n)]
def SRL(n): return [list(S()) for i in range(n)]
def MSRL(n): return [[int(j) for j in list(S())] for i in range(n)]
mod = 1000000007


class Segtree:
    def __init__(self, A, ide_ele, segfunc, initialize=True):
        self.n = len(A)
        self.size = 2 ** (self.n - 1).bit_length()
        self.ide_ele = ide_ele
        self.segfunc = segfunc
        if initialize:
            self.data = [ide_ele] * self.size + A + [ide_ele] * (self.size - self.n)
            for i in range(self.size - 1, 0, -1):
                self.data[i] = self.segfunc(self.data[2 * i], self.data[2 * i + 1])
        else:
            self.data = [ide_ele] * (2 * self.size)

    def update(self, k, x):
        k += self.size
        self.data[k] = x
        while k > 0:
            k = k >> 1
            self.data[k] = self.segfunc(self.data[2 * k], self.data[2 * k + 1])

    def query(self, l, r):
        L, R = l + self.size, r + self.size
        s = self.ide_ele
        while L < R:
            if R & 1:
                R -= 1
                s = self.segfunc(s, self.data[R])
            if L & 1:
                s = self.segfunc(s, self.data[L])
                L += 1
            L >>= 1
            R >>= 1
        return s

n = I()
P = LI()
D = {P[i]: i for i in range(n)}
p_even = [P[i] if not i & 1 else INF for i in range(n)]
p_odd = [P[i] if i & 1 else INF for i in range(n)]
st_even = Segtree(p_even, INF, min)
st_odd = Segtree(p_odd, INF, min)
hq = [(st_even.query(0, n), 0, n)]
ans = []
for _ in range(n // 2):
    v1, l, r = heappop(hq)
    p1 = D[v1]
    if not l & 1:
        st1, st2 = st_odd, st_even
    else:
        st1, st2 = st_even, st_odd
    v2 = st1.query(p1, r)
    p2 = D[v2]
    st2.update(p1, INF)
    st1.update(p2, INF)
    if l != p1:
        heappush(hq, (st2.query(l, p1), l, p1))
    if p1 + 1 != p2:
        heappush(hq, (st1.query(p1 + 1, p2), p1 + 1, p2))
    if p2 + 1 != r:
        heappush(hq, (st2.query(p2 + 1, r), p2 + 1, r))
    ans += [v1, v2]


print(*ans)

Solution (Python):
from heapq import *
import sys

sys.setrecursionlimit(10 ** 6)
int1 = lambda x: int(x) - 1
p2D = lambda x: print(*x, sep="\n")
def MI(): return map(int, sys.stdin.readline().split())
def LI(): return list(map(int, sys.stdin.readline().split()))
def LLI(rows_number): return [LI() for _ in range(rows_number)]


class SparseTable:
    def __init__(self, aa):
        inf = 10 ** 16
        w = len(aa)
        h = w.bit_length()
        table = [aa] * 2 + [[inf] * w for _ in range(h - 2)]
        tablei1 = table[0]
        for i in range(2, h):
            tablei = table[i]
            shift = 1 << (i - 1)
            for j in range(w):
                rj = j + shift
                if rj >= w: break
                tablei[j] = min(tablei1[j], tablei1[rj])
            tablei1 = tablei
        self.table = table

    
    def min(self, l, r):
        if (r - l) % 2: r += 1
        i = (r - l).bit_length() - 1
        tablei = self.table[i]
        Lmin = tablei[l]
        Rmin = tablei[r - (1 << i)]
        if Lmin < Rmin: Rmin = Lmin
        return Rmin

def main():
    n = int(input())
    pp = LI()
    st = SparseTable(pp)
    ptoi = [0] + [i for i, p in sorted(enumerate(pp), key=lambda x: x[1])]
    
    hp = []
    heappush(hp, [st.min(0, n), 0, n])
    ans = []
    for _ in range(n // 2):
        x, l, r = heappop(hp)
        if l + 2 == r:
            ans += [pp[l], pp[l + 1]]
            continue
        xi = ptoi[x]
        y = st.min(xi + 1, r)
        yi = ptoi[y]
        if xi > l:
            heappush(hp, [st.min(l, xi), l, xi])
        if xi + 1 < yi:
            heappush(hp, [st.min(xi + 1, yi), xi + 1, yi])
        if yi < r - 1:
            heappush(hp, [st.min(yi + 1, r), yi + 1, r])
        ans += [x, y]
    print(*ans)

main()

Solution (Python):
import sys
readline = sys.stdin.readline
from heapq import heappop as hpp, heappush as hp
class Segtree:
    def __init__(self, A, intv, initialize = True, segf = max):
        self.N = len(A)
        self.N0 = 2**(self.N-1).bit_length()
        self.intv = intv
        self.segf = segf
        if initialize:
            self.data = [intv]*self.N0 + A + [intv]*(self.N0 - self.N)
            for i in range(self.N0-1, 0, -1):
                self.data[i] = self.segf(self.data[2*i], self.data[2*i+1]) 
        else:
            self.data = [intv]*(2*self.N0)
        
    def update(self, k, x):
        k += self.N0
        self.data[k] = x
        while k > 0 :
            k = k >> 1
            self.data[k] = self.segf(self.data[2*k], self.data[2*k+1])
    
    def query(self, l, r):
        L, R = l+self.N0, r+self.N0
        s = self.intv
        while L < R:
            if R & 1:
                R -= 1
                s = self.segf(s, self.data[R])
            if L & 1:
                s = self.segf(s, self.data[L])
                L += 1
            L >>= 1
            R >>= 1
        return s
    
    def binsearch(self, l, r, check, reverse = False):
        L, R = l+self.N0, r+self.N0
        SL, SR = [], []
        while L < R:
            if R & 1:
                R -= 1
                SR.append(R)
            if L & 1:
                SL.append(L)
                L += 1
            L >>= 1
            R >>= 1
        
        if reverse:
            for idx in (SR + SL[::-1]):
                if check(self.data[idx]):
                    break
            else:
                return -1
            while idx < self.N0:
                if check(self.data[2*idx+1]):
                    idx = 2*idx + 1
                else:
                    idx = 2*idx
            return idx
        else:
            for idx in (SL + SR[::-1]):
                if check(self.data[idx]):
                    break
            else:
                return -1
            while idx < self.N0:
                if check(self.data[2*idx]):
                    idx = 2*idx
                else:
                    idx = 2*idx + 1
            return idx

N = int(readline())

inf = 1<<32
P = list(map(int, readline().split()))

Pi = [None]*(N+1)
for i in range(N):
    Pi[P[i]] = i

inf = 1<<32
Peven = [P[i] if not i&1 else inf for i in range(N)]
Podd = [P[i] if i&1 else inf for i in range(N)]

Teven = Segtree(Peven, inf, initialize = True, segf = min)
Todd = Segtree(Podd, inf, initialize = True, segf = min)
N0 = 2**(N-1).bit_length()

Q = [(Teven.query(0, N0), 0, N0)]
for i in range(N//2):
    t1, l, r = hpp(Q)
    K = []
    if not l&1:
        p1 = Pi[t1]
        t2 = Todd.query(p1, r)
        p2 = Pi[t2]
        Teven.update(p1, inf)
        Todd.update(p2, inf)
    else:
        p1 = Pi[t1]
        t2 = Teven.query(p1, r)
        p2 = Pi[t2]
        Todd.update(p1, inf)
        Teven.update(p2, inf)
    if l < p1:
        K.append((l, p1))
    if p2 < r:
        K.append((p2+1, r))
    if p1 + 1 < p2:
        K.append((p1+1, p2))
    for l, r in K:
        if not l&1:
            mq = Teven.query(l, r)
        else:
            mq = Todd.query(l, r)
        hp(Q, (mq, l, r))
    sys.stdout.write('{} {} '.format(t1, t2))
sys.stdout.write('\n')

Solution (Python):
class SegTree:
    def __init__(self, init_val, ide_ele, segfunc):
        self.n = len(init_val)
        self.num =2**(self.n-1).bit_length()
        self.ide_ele = ide_ele
        self.seg = [self.ide_ele]*2*self.num
        self.segfunc = segfunc
        
        
        for i in range(self.n):
            self.seg[i+self.num-1] = init_val[i]    
        
        for i in range(self.num-2,-1,-1) :
            self.seg[i] = segfunc(self.seg[2*i+1], self.seg[2*i+2]) 
    
    def update(self, k, x):
        k += self.num-1
        self.seg[k] = x
        while k+1:
            k = (k-1)//2
            self.seg[k] = self.segfunc(self.seg[k*2+1], self.seg[k*2+2])
    
    def query(self, p, q):
        if q<=p:
            return self.ide_ele
        p += self.num-1
        q += self.num-2
        res = self.ide_ele
        while q-p>1:
            if p&1 == 0:
                res = self.segfunc(res, self.seg[p])
            if q&1 == 1:
                res = self.segfunc(res, self.seg[q])
                q -= 1
            p = p//2
            q = (q-1)//2
        if p == q:
            res = self.segfunc(res, self.seg[p])
        else:
            res = self.segfunc(self.segfunc(res, self.seg[p]), self.seg[q])
        return res

def main():
    import sys
    input = sys.stdin.readline
    
    N = int(input())
    P = list(map(int,input().split()))
    Even = []
    Odd = []
    D = {}
    for i in range(N//2):
        e = P[2*i]
        o = P[2*i+1]
        D[e] = i
        D[o] = i
        Even.append(e)
        Odd.append(o)
    
    E_Seg = SegTree(Even,float("inf"),min)
    O_Seg = SegTree(Odd,float("inf"),min)
    
    import heapq
    heap = []
    
    
    
    def BFS(H):
        L = H[0]
        R = H[1]
        if R <= L:
            return -1,-1,-1,-1,-1
        if L%2==0:
            l = L//2
            r = R//2
            mini = E_Seg.query(l,r+1)
            d_mini = D[mini]
            mini_b = O_Seg.query(d_mini, r+1)
            d_mini_b = D[mini_b]
            
            leftH = (L, 2*d_mini-1)
            centH = (2*d_mini+1, 2*d_mini_b)
            rightH = (2*d_mini_b+2, R)
            return mini, mini_b, leftH, centH, rightH
        else:
            l = L//2
            r = R//2
            mini = O_Seg.query(l, r)
            d_mini = D[mini]
            mini_b = E_Seg.query(d_mini+1, r+1)
            d_mini_b = D[mini_b]
            
            leftH = (L, 2*d_mini)
            centH = (2*d_mini+2, 2*d_mini_b-1)
            rightH = (2*d_mini_b+1, R)
            return mini, mini_b, leftH, centH, rightH
        
    H = (0, N-1)
    m1,m2,LH,CH,RH = BFS(H)
    
    heapq.heappush(heap, [m1,m2,LH,CH,RH])
    Q = []
    while heap != []:
        m1,m2,LH,CH,RH = heapq.heappop(heap)
        Q += [m1,m2]
        
        m1L,m2L,LHL,CHL,RHL = BFS(LH)
        if m1L != -1:
            heapq.heappush(heap, [m1L,m2L,LHL,CHL,RHL])
        
        m1C,m2C,LHC,CHC,RHC = BFS(CH)
        if m1C != -1:
            heapq.heappush(heap, [m1C,m2C,LHC,CHC,RHC])
        
        m1R,m2R,LHR,CHR,RHR = BFS(RH)
        if m1R != -1:
            heapq.heappush(heap, [m1R,m2R,LHR,CHR,RHR])
    print(*Q)
    
    
    
    
main()

Solution (Python):
from heapq import heappop, heappush
INF = 10**30

class Rmin():
	def __init__(self, size):
		
		self.n = 1
		while self.n < size:
			self.n *= 2
		self.node = [INF] * (2*self.n-1)

	def Access(self, x):
		return self.node[x+self.n-1]

	def Update(self, x, val):
		x += self.n-1
		self.node[x] = val
		while x > 0:
			x = (x-1)//2
			self.node[x] = min(self.node[2*x+1], self.node[2*x+2])
		return

	
	def Get(self, l, r):
		L, R = l+self.n, r+self.n
		s = INF
		while L < R:
			if R & 1:
				R -= 1
				s = min(s, self.node[R-1])			
			if L & 1:
				s = min(s, self.node[L-1])
				L += 1
			L >>= 1
			R >>= 1
		return s

n = int(input())
a = list(map(int, input().split()))

even, odd = Rmin(n), Rmin(n)
for i in range(n):
	if i%2 == 0:
		even.Update(i, a[i]*(10**7) + i)
	else:
		odd.Update(i, a[i]*(10**7) + i)

d = dict()

def search(l, r):
	if l%2 == 0:
		p = even.Get(l, r+1)
		q = odd.Get(p%(10**7)+1, r+1)
	else:
		p = odd.Get(l, r+1)
		q = even.Get(p%(10**7)+1, r+1)
	return p, q

x, y = search(0, n-1)
d[x%(10**7)] = (y, 0, n-1)
que = [x]
ans = []

while que:
	x = heappop(que)
	y, l, r = d[x%(10**7)]
	ans += [x//(10**7), y//(10**7)]

	if l != x%(10**7):
		p, q = search(l, x%(10**7)-1)
		d[p%(10**7)] = (q, l, x%(10**7)-1)
		heappush(que, p)

	if r != y%(10**7):
		p, q = search(y%(10**7)+1, r)
		d[p%(10**7)] = (q, y%(10**7)+1, r)
		heappush(que, p)

	if x%(10**7)+1 != y%(10**7):
		p, q = search(x%(10**7)+1, y%(10**7)-1)
		d[p%(10**7)] = (q, x%(10**7)+1, y%(10**7)-1)
		heappush(que, p)

print(*ans)

Solution (Python):
import sys
input = sys.stdin.readline
from heapq import heappush, heappop

N = int(input())
A = [int(x) for x in input().split()]
a_to_i = {a:i for i,a in enumerate(A)}




U = len(A).bit_length()
sp = [None,A]
for i in range(2,U):
    L = 1 << (i-1)
    sp.append([x if x < y else y for x,y in zip(sp[-1][:-L], sp[-1][L:])])

def RMQ(x,y):
    
    d = y - x
    if d <= 1:
        return A[x]
    n = d.bit_length()
    arr = sp[n-1]
    ax = arr[x]
    ay = arr[y+2-(1<<(n-1))]
    return ax if ax < ay else ay

def F(x,y):
    
    
    x1 = RMQ(x,y-1)
    i1 = a_to_i[x1]
    x2 = RMQ(i1+1,y)
    i2 = a_to_i[x2]
    task = ((x,y) for x,y in ((x,i1-1), (i1+1,i2-1), (i2+1,y)) if y > x)
    return x1,x2,task

q = [(None,None,((0,N-1),))]
answer = []
while q:
    x,y,task = heappop(q)
    answer.append(x)
    answer.append(y)
    for left,right in task:
        heappush(q,F(left,right))

print(' '.join(map(str,answer[2:])))

Solution (Python):
import sys
input = sys.stdin.readline
from heapq import heappush, heappop

N = int(input())
A = [int(x) for x in input().split()]
a_to_i = {a:i for i,a in enumerate(A)}




U = len(A).bit_length()
sp = [None,A]
for i in range(2,U):
    L = 1 << (i-1)
    sp.append([x if x < y else y for x,y in zip(sp[-1][:-L], sp[-1][L:])])

def RMQ(x,y):
    
    d = y - x
    if d <= 1:
        return A[x]
    n = d.bit_length()
    return min(sp[n-1][x], sp[n-1][y+2-(1<<(n-1))])

def F(x,y):
    
    
    x1 = RMQ(x,y-1)
    i1 = a_to_i[x1]
    x2 = RMQ(i1+1,y)
    i2 = a_to_i[x2]
    task = ((x,y) for x,y in ((x,i1-1), (i1+1,i2-1), (i2+1,y)) if y > x)
    return x1,x2,task

q = [(None,None,((0,N-1),))]
answer = []
while q:
    x,y,task = heappop(q)
    answer.append(x)
    answer.append(y)
    for left,right in task:
        heappush(q,F(left,right))

print(' '.join(map(str,answer[2:])))

Solution (Python):
import sys
input = sys.stdin.readline
import numpy as np
from heapq import heappush, heappop

N = int(input())
A = np.array(input().split(), dtype=np.int32)
a_to_i = {a:i for i,a in enumerate(A)}




U = len(A).bit_length()
sp = [None,A]
for i in range(2,U):
    L = 1 << (i-1)
    sp.append(np.minimum(sp[-1][:-L], sp[-1][L:]))

def RMQ(x,y):
    
    d = y - x
    if d <= 1:
        return A[x]
    n = d.bit_length()
    return min(sp[n-1][x], sp[n-1][y+2-(1<<(n-1))])

def F(x,y):
    
    
    x1 = RMQ(x,y-1)
    i1 = a_to_i[x1]
    x2 = RMQ(i1+1,y)
    i2 = a_to_i[x2]
    task = ((x,y) for x,y in ((x,i1-1), (i1+1,i2-1), (i2+1,y)) if y > x)
    return x1,x2,task

q = [(None,None,((0,N-1),))]
answer = []
while q:
    x,y,task = heappop(q)
    answer.append(x)
    answer.append(y)
    for left,right in task:
        heappush(q,F(left,right))

print(' '.join(map(str,answer[2:])))

Solution (Python):
import sys
input = sys.stdin.readline
import numpy as np
from heapq import heappush, heappop

N = int(input())
A = np.array(input().split(), dtype=np.int32)
a_to_i = {a:i for i,a in enumerate(A)}




U = len(A).bit_length()
sp = [None,A]
for i in range(2,U):
    L = 1 << (i-1)
    sp.append(np.minimum(sp[-1][:-L], sp[-1][L:]))

def RMQ(x,y):
    if (y-x)&1: 
        y -= 1
    
    d = y - x
    if d <= 1:
        return A[x]
    n = d.bit_length()
    return min(sp[n-1][x], sp[n-1][y+2-(1<<(n-1))])

def F(x,y):
    
    
    x1 = RMQ(x,y)
    i1 = a_to_i[x1]
    x2 = RMQ(i1+1,y)
    i2 = a_to_i[x2]
    task = ((x,y) for x,y in ((x,i1-1), (i1+1,i2-1), (i2+1,y)) if y > x)
    return x1,x2,task

q = [(None,None,((0,N-1),))]
answer = []
while q:
    x,y,task = heappop(q)
    if x != None:
        answer.append(x)
        answer.append(y)
    for left,right in task:
        heappush(q,F(left,right))

print(' '.join(map(str,answer)))

Solution (Python):

N = int(input())
*P, = map(int, input().split())
M = [0]*(N+1)
for i, p in enumerate(P):
    M[p] = i

INF = 10**9
def init(P, n):
    n0 = 2 ** (n-1).bit_length()
    data = [INF]*(n0*2)
    data[n0-1:n0+n-1] = P
    for i in range(n0-2, -1, -1):
        data[i] = min(data[2*i+1], data[2*i+2])
    return data

def get_data(data, l, r):
    n0 = len(data)//2
    l += n0
    r += n0
    while l < r:
        if r&1:
            r -= 1
            yield data[r-1]
        if l&1:
            yield data[l-1]
            l += 1
        l >>= 1
        r >>= 1

def get(data, l, r):
    return min(get_data(data, l, r))

d0 = init(P[0::2], N//2)
d1 = init(P[1::2], N//2)

def query_x(l, r):
    if l % 2 == 0:
        x = get(d0, l//2, r//2)
    else:
        x = get(d1, l//2, r//2)
    return x
def query_y(l, r):
    if l % 2 == 0:
        y = get(d1, l//2, r//2)
    else:
        y = get(d0, (l+1)//2, (r+1)//2)
    return y

from heapq import heappush, heappop
que = [(query_x(0, N), 0, N)]
ans = []
while que:
    x, l, r = heappop(que)
    if l+2 < r:
        xi = M[x]
        y = query_y(xi, r)

        yi = M[y]

        
        if l < xi:
            heappush(que, (query_x(l, xi), l, xi))
        
        if xi+1 < yi:
            heappush(que, (query_x(xi+1, yi), xi+1, yi))
        
        if yi+1 < r:
            heappush(que, (query_x(yi+1, r), yi+1, r))
    else:
        y = P[r-1]

    ans.append("%d %d" % (x, y))
print(*ans)

Solution (Python):

N = int(input())
*P, = map(int, input().split())
M = [0]*(N+1)
for i, p in enumerate(P):
    M[p] = i

INF = 10**9
def init(P, n):
    n0 = 2 ** (n-1).bit_length()
    data = [INF]*(n0*2)
    data[n0-1:n0+n-1] = P
    for i in range(n0-2, -1, -1):
        data[i] = min(data[2*i+1], data[2*i+2])
    return data

def get_data(data, l, r):
    n0 = len(data)//2
    l += n0
    r += n0
    while l < r:
        if r&1:
            r -= 1
            yield data[r-1]
        if l&1:
            yield data[l-1]
            l += 1
        l >>= 1
        r >>= 1

def get(data, l, r):
    return min(get_data(data, l, r))

d0 = init(P[0::2], N//2)
d1 = init(P[1::2], N//2)

def query_x(l, r):
    if l % 2 == 0:
        x = get(d0, l//2, r//2)
    else:
        x = get(d1, l//2, r//2)
    return x
def query_y(l, r):
    if l % 2 == 0:
        y = get(d1, l//2, r//2)
    else:
        y = get(d0, (l+1)//2, (r+1)//2)
    return y

from heapq import heappush, heappop
que = [(query_x(0, N), 0, N)]
ans = []
while que:
    x, l, r = heappop(que)
    if l+2 < r:
        xi = M[x]
        y = query_y(xi, r)

        yi = M[y]

        
        if l < xi:
            heappush(que, (query_x(l, xi), l, xi))
        
        if xi+1 < yi:
            heappush(que, (query_x(xi+1, yi), xi+1, yi))
        
        if yi+1 < r:
            heappush(que, (query_x(yi+1, r), yi+1, r))
    else:
        y = P[r-1]

    ans.append("%d %d" % (x, y))
print(*ans)