Problem p03641 (C++)

Buggy submission (status: Runtime Error):
#define _USE_MATH_DEFINES
#include "bits/stdc++.h"
using namespace std;

#define int long long
typedef pair<int, int> P;

int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};

/*
#define cin ifs
#define cout ofs
ifstream ifs("in.txt");
ofstream ofs("out.txt");
//*/

#include "bits/stdc++.h"
using namespace std;

#define int long long

// セグ木を用いたRMQ
const int MAX_N = 220000;

struct RMQ {
  int n, dat[2 * MAX_N - 1];

  void init(int n_) {
    n = 1;
    while (n < n_)
      n *= 2;
    for (int i = 0; i < 2 * n - 1; i++)
      dat[i] = LLONG_MAX;
  }

  void update(int k, int a) {
    k += n - 1;
    dat[k] = a;
    while (k > 0) {
      k = (k - 1) / 2;
      dat[k] = min(dat[k * 2 + 1], dat[k * 2 + 2]);
    }
  }

  int query(int a, int b, int k, int l, int r) {
    if (r <= a || b <= l)
      return LLONG_MAX;
    if (a <= l && r <= b)
      return dat[k];
    else {
      int vl = query(a, b, k * 2 + 1, l, (l + r) / 2);
      int vr = query(a, b, k * 2 + 2, (l + r) / 2, r);
      return min(vl, vr);
    }
  }
};

typedef pair<int, P> seg;
RMQ rmq0, rmq1;
int N;
int p[220000], ap[220000];

// [l, r)
seg getSeg(int l, int r) {
  int pri;
  if (l % 2 == 0)
    pri = rmq0.query(l, r, 0, 0, rmq0.n);
  else
    pri = rmq1.query(l, r, 0, 0, rmq1.n);
  return seg(pri, P(l, r));
}

signed main() {
  cin >> N;
  rmq0.init(N + 10), rmq1.init(N + 10);
  for (int i = 0; i < N; i++) {
    cin >> p[i];
    ap[p[i]] = i;
    if (i % 2 == 0)
      rmq0.update(i, p[i]);
    else
      rmq1.update(i, p[i]);
  }
  priority_queue<seg, vector<seg>, greater<seg>> pq;
  pq.push(getSeg(0, N));
  for (int i = 0; i < N / 2; i++) {
    seg cur = pq.top();
    pq.pop();
    int l = cur.second.first, r = cur.second.second;
    int mid = ap[cur.first];
    cout << cur.first << " ";
    if (l != mid)
      pq.push(getSeg(l, mid));
    int pri;
    if ((mid + 1) % 2 == 0)
      pri = rmq0.query(mid + 1, r, 0, 0, rmq0.n);
    else
      pri = rmq1.query(mid + 1, r, 0, 0, rmq1.n);
    cout << pri << " ";
    int nid = ap[pri];
    if (mid + 1 != nid)
      pq.push(getSeg(mid + 1, nid));
    if (nid + 1 != r)
      pq.push(getSeg(nid + 1, r));
  }
  cout << endl;
  return 0;
}

Fixed submission:
#define _USE_MATH_DEFINES
#include "bits/stdc++.h"
using namespace std;

#define int long long
typedef pair<int, int> P;

int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};

/*
#define cin ifs
#define cout ofs
ifstream ifs("in.txt");
ofstream ofs("out.txt");
//*/

#include "bits/stdc++.h"
using namespace std;

#define int long long

// セグ木を用いたRMQ
const int MAX_N = 420000;

struct RMQ {
  int n, dat[2 * MAX_N - 1];

  void init(int n_) {
    n = 1;
    while (n < n_)
      n *= 2;
    for (int i = 0; i < 2 * n - 1; i++)
      dat[i] = LLONG_MAX;
  }

  void update(int k, int a) {
    k += n - 1;
    dat[k] = a;
    while (k > 0) {
      k = (k - 1) / 2;
      dat[k] = min(dat[k * 2 + 1], dat[k * 2 + 2]);
    }
  }

  int query(int a, int b, int k, int l, int r) {
    if (r <= a || b <= l)
      return LLONG_MAX;
    if (a <= l && r <= b)
      return dat[k];
    else {
      int vl = query(a, b, k * 2 + 1, l, (l + r) / 2);
      int vr = query(a, b, k * 2 + 2, (l + r) / 2, r);
      return min(vl, vr);
    }
  }
};

typedef pair<int, P> seg;
RMQ rmq0, rmq1;
int N;
int p[220000], ap[220000];

// [l, r)
seg getSeg(int l, int r) {
  int pri;
  if (l % 2 == 0)
    pri = rmq0.query(l, r, 0, 0, rmq0.n);
  else
    pri = rmq1.query(l, r, 0, 0, rmq1.n);
  return seg(pri, P(l, r));
}

signed main() {
  cin >> N;
  rmq0.init(N + 10), rmq1.init(N + 10);
  for (int i = 0; i < N; i++) {
    cin >> p[i];
    ap[p[i]] = i;
    if (i % 2 == 0)
      rmq0.update(i, p[i]);
    else
      rmq1.update(i, p[i]);
  }
  priority_queue<seg, vector<seg>, greater<seg>> pq;
  pq.push(getSeg(0, N));
  for (int i = 0; i < N / 2; i++) {
    seg cur = pq.top();
    pq.pop();
    int l = cur.second.first, r = cur.second.second;
    int mid = ap[cur.first];
    cout << cur.first << " ";
    if (l != mid)
      pq.push(getSeg(l, mid));
    int pri;
    if ((mid + 1) % 2 == 0)
      pri = rmq0.query(mid + 1, r, 0, 0, rmq0.n);
    else
      pri = rmq1.query(mid + 1, r, 0, 0, rmq1.n);
    cout << pri << " ";
    int nid = ap[pri];
    if (mid + 1 != nid)
      pq.push(getSeg(mid + 1, nid));
    if (nid + 1 != r)
      pq.push(getSeg(nid + 1, r));
  }
  cout << endl;
  return 0;
}