Problem p03641 (C++)

Buggy submission (status: Runtime Error):
#include "bits/stdc++.h"
using namespace std;
#define ll long long int
#define rep(i, n) for (int i = 0; i < n; i++)
#define rrep(i, n) for (int i = n; i >= 0; i--)
#define REP(i, s, t) for (int i = s; i <= t; i++)
#define RREP(i, s, t) for (int i = s; i >= t; i--)
#define dump(x) cerr << #x << " = " << (x) << endl;
#define INF 2000000000
#define mod 1000000007
#define INF2 1000000000000000000
const int MAX_N = 300010;
int n;
template <class V, int NV> struct SegTree {
  V comp(V l, V r) { return min(l, r); };

  vector<V> dat;

  SegTree() {
    dat = vector<V>(MAX_N, {INF, INF});
    n = 1;
    while (n < NV)
      n *= 2;
    rep(i, 2 * n - 1) dat[i] = {INF, INF};
  }

  // k番目の値(0-indexed)をaに変更
  void update(int k, V a) {
    k += n - 1;
    dat[k] = a;
    while (k > 0) {
      k = (k - 1) / 2;
      dat[k] = comp(dat[k * 2 + 1], dat[k * 2 + 2]);
    }
  }
  // [a, b)の最小値を探す．
  V query(int a, int b, int k, int l, int r) {
    if (r <= a || b <= l)
      return {INF, INF};
    if (a <= l && r <= b)
      return dat[k];
    else {
      V vl = query(a, b, k * 2 + 1, l, (l + r) / 2);
      V vr = query(a, b, k * 2 + 2, (l + r) / 2, r);
      return comp(vl, vr);
    }
  }
};
int N, p[200010];
SegTree<pair<int, int>, 1 << 18> st1, st2;

vector<int> E[200010];
int pR[200010];

void dfs(int L, int R, int pa = 0) {
  // cout <<"*"<< L << " " << R << endl;
  pair<int, int> mi1, mi2;
  // 区間が2であれば、ペアが確定
  if (L + 1 == R) {
    E[pa].push_back(p[L]);
    pR[p[L]] = p[R];
    return;
  }

  if (L % 2 == 0) {
    mi1 = st1.query(L, R, 0, 0, n);
    mi2 = st2.query(mi1.second + 1, R + 1, 0, 0, n);
  } else {
    mi1 = st2.query(L, R, 0, 0, n);
    mi2 = st1.query(mi1.second + 1, R + 1, 0, 0, n);
  }
  int i = mi1.second;
  int j = mi2.second;
  // cout << mi1.first << " " << mi2.first << endl;
  // ペアが決まったので、代入
  E[pa].push_back(mi1.first);
  pR[mi1.first] = mi2.first;
  // cout << "OK" << endl;
  if (L != i)
    dfs(L, i - 1, mi1.first);
  if (i + 1 != j)
    dfs(i + 1, j - 1, mi1.first);
  if (R != j)
    dfs(j + 1, R, mi1.first);
}

int main(void) {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cin >> N;
  rep(i, N) cin >> p[i];
  rep(i, N) {
    if (i % 2 == 0)
      st1.update(i, {p[i], i});
    else
      st2.update(i, {p[i], i});
  }

  dfs(0, N - 1);

  vector<int> ans;
  priority_queue<int, vector<int>, greater<int>> que;
  que.push(E[0].front());

  while (!que.empty()) {
    int q = que.top();
    que.pop();

    ans.push_back(q);
    ans.push_back(pR[q]);

    for (auto x : E[q])
      que.push(x);
  }
  rep(i, N) {
    if (i != 0)
      cout << " ";
    cout << ans[i];
  }
  cout << endl;

  return 0;
}


Fixed submission:
#include "bits/stdc++.h"
using namespace std;
#define ll long long int
#define rep(i, n) for (int i = 0; i < n; i++)
#define rrep(i, n) for (int i = n; i >= 0; i--)
#define REP(i, s, t) for (int i = s; i <= t; i++)
#define RREP(i, s, t) for (int i = s; i >= t; i--)
#define dump(x) cerr << #x << " = " << (x) << endl;
#define INF 2000000000
#define mod 1000000007
#define INF2 1000000000000000000
const int MAX_N = 1 << 19;
int n;
template <class V, int NV> struct SegTree {
  V comp(V l, V r) { return min(l, r); };

  vector<V> dat;

  SegTree() {
    dat = vector<V>(MAX_N, {INF, INF});
    n = 1;
    while (n < NV)
      n *= 2;
    rep(i, 2 * n - 1) dat[i] = {INF, INF};
  }

  // k番目の値(0-indexed)をaに変更
  void update(int k, V a) {
    k += n - 1;
    dat[k] = a;
    while (k > 0) {
      k = (k - 1) / 2;
      dat[k] = comp(dat[k * 2 + 1], dat[k * 2 + 2]);
    }
  }
  // [a, b)の最小値を探す．
  V query(int a, int b, int k, int l, int r) {
    if (r <= a || b <= l)
      return {INF, INF};
    if (a <= l && r <= b)
      return dat[k];
    else {
      V vl = query(a, b, k * 2 + 1, l, (l + r) / 2);
      V vr = query(a, b, k * 2 + 2, (l + r) / 2, r);
      return comp(vl, vr);
    }
  }
};
int N, p[200010];
SegTree<pair<int, int>, 1 << 18> st1, st2;

vector<int> E[200010];
int pR[200010];

void dfs(int L, int R, int pa = 0) {
  // cout <<"*"<< L << " " << R << endl;
  pair<int, int> mi1, mi2;
  // 区間が2であれば、ペアが確定
  if (L + 1 == R) {
    E[pa].push_back(p[L]);
    pR[p[L]] = p[R];
    return;
  }

  if (L % 2 == 0) {
    mi1 = st1.query(L, R, 0, 0, n);
    mi2 = st2.query(mi1.second + 1, R + 1, 0, 0, n);
  } else {
    mi1 = st2.query(L, R, 0, 0, n);
    mi2 = st1.query(mi1.second + 1, R + 1, 0, 0, n);
  }
  int i = mi1.second;
  int j = mi2.second;
  // cout << mi1.first << " " << mi2.first << endl;
  // ペアが決まったので、代入
  E[pa].push_back(mi1.first);
  pR[mi1.first] = mi2.first;
  // cout << "OK" << endl;
  if (L != i)
    dfs(L, i - 1, mi1.first);
  if (i + 1 != j)
    dfs(i + 1, j - 1, mi1.first);
  if (R != j)
    dfs(j + 1, R, mi1.first);
}

int main(void) {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cin >> N;
  rep(i, N) cin >> p[i];
  rep(i, N) {
    if (i % 2 == 0)
      st1.update(i, {p[i], i});
    else
      st2.update(i, {p[i], i});
  }

  dfs(0, N - 1);

  vector<int> ans;
  priority_queue<int, vector<int>, greater<int>> que;
  que.push(E[0].front());

  while (!que.empty()) {
    int q = que.top();
    que.pop();

    ans.push_back(q);
    ans.push_back(pR[q]);

    for (auto x : E[q])
      que.push(x);
  }
  rep(i, N) {
    if (i != 0)
      cout << " ";
    cout << ans[i];
  }
  cout << endl;

  return 0;
}