Problem p03641 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 9, INF = 0x3f3f3f3f;

#define L (x << 1)
#define R (x << 1 | 1)
int mi[N][2], p[N], n, pp[N];
bool vis[N];

void update(int x) {
  mi[x][0] = p[mi[L][0]] < p[mi[R][0]] ? mi[L][0] : mi[R][0];
  mi[x][1] = p[mi[L][1]] < p[mi[R][1]] ? mi[L][1] : mi[R][1];
}

void Build(int x, int l, int r) {
  if (l == r) {
    if (l & 1)
      mi[x][1] = l, mi[x][0] = 0;
    else
      mi[x][0] = l, mi[x][1] = 0;
    return;
  }
  int mid = (l + r) >> 1;
  Build(L, l, mid);
  Build(R, mid + 1, r);
  update(x);
}

int Query(int x, int l, int r, int ql, int qr, bool o) {
  if (ql > qr || ql > n)
    return INF;
  if (l == ql && r == qr)
    return mi[x][o];
  int mid = (l + r) >> 1;
  if (qr <= mid)
    return Query(L, l, mid, ql, qr, o);
  if (ql > mid)
    return Query(R, mid + 1, r, ql, qr, o);
  int al = Query(L, l, mid, ql, mid, o),
      ar = Query(R, mid + 1, r, mid + 1, qr, o);
  return p[al] < p[ar] ? al : ar;
}

struct it {
  int l, r, al, ar;
  it(int l, int r) : l(l), r(r) {
    al = Query(1, 1, n, l, r, l & 1),
    ar = Query(1, 1, n, al + 1, r, (l & 1) ^ 1);
  }
  bool operator<(const it &rhs) const { return p[al] > p[rhs.al]; }
};

priority_queue<it> Q;

int main() {
  scanf("%d", &n);
  p[0] = INF;
  for (int i = 1; i <= n; ++i)
    scanf("%d", &p[i]), pp[p[i]] = i;
  Build(1, 1, n);
  Q.push(it(1, n));
  int l, r, al, ar;
  while (!Q.empty()) {
    l = Q.top().l;
    r = Q.top().r;
    al = Q.top().al;
    ar = Q.top().ar;
    Q.pop();
    printf("%d %d ", p[al], p[ar]);
    if (l < al)
      Q.push(it(l, al - 1));
    if (ar < r)
      Q.push(it(ar + 1, r));
    if (al + 1 < ar)
      Q.push(it(al + 1, ar - 1));
  }
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
const int N = 8e5 + 9, INF = 0x3f3f3f3f;

#define L (x << 1)
#define R (x << 1 | 1)
int mi[N][2], p[N], n, pp[N];
bool vis[N];

void update(int x) {
  mi[x][0] = p[mi[L][0]] < p[mi[R][0]] ? mi[L][0] : mi[R][0];
  mi[x][1] = p[mi[L][1]] < p[mi[R][1]] ? mi[L][1] : mi[R][1];
}

void Build(int x, int l, int r) {
  if (l == r) {
    if (l & 1)
      mi[x][1] = l, mi[x][0] = 0;
    else
      mi[x][0] = l, mi[x][1] = 0;
    return;
  }
  int mid = (l + r) >> 1;
  Build(L, l, mid);
  Build(R, mid + 1, r);
  update(x);
}

int Query(int x, int l, int r, int ql, int qr, bool o) {
  if (ql > qr || ql > n)
    return INF;
  if (l == ql && r == qr)
    return mi[x][o];
  int mid = (l + r) >> 1;
  if (qr <= mid)
    return Query(L, l, mid, ql, qr, o);
  if (ql > mid)
    return Query(R, mid + 1, r, ql, qr, o);
  int al = Query(L, l, mid, ql, mid, o),
      ar = Query(R, mid + 1, r, mid + 1, qr, o);
  return p[al] < p[ar] ? al : ar;
}

struct it {
  int l, r, al, ar;
  it(int l, int r) : l(l), r(r) {
    al = Query(1, 1, n, l, r, l & 1),
    ar = Query(1, 1, n, al + 1, r, (l & 1) ^ 1);
  }
  bool operator<(const it &rhs) const { return p[al] > p[rhs.al]; }
};

priority_queue<it> Q;

int main() {
  scanf("%d", &n);
  p[0] = INF;
  for (int i = 1; i <= n; ++i)
    scanf("%d", &p[i]), pp[p[i]] = i;
  Build(1, 1, n);
  Q.push(it(1, n));
  int l, r, al, ar;
  while (!Q.empty()) {
    l = Q.top().l;
    r = Q.top().r;
    al = Q.top().al;
    ar = Q.top().ar;
    Q.pop();
    printf("%d %d ", p[al], p[ar]);
    if (l < al)
      Q.push(it(l, al - 1));
    if (ar < r)
      Q.push(it(ar + 1, r));
    if (al + 1 < ar)
      Q.push(it(al + 1, ar - 1));
  }
  return 0;
}