Problem p03641 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cstdio>
#include <queue>
using namespace std;

const int INF = 987654321;
const int SIZE = 200001;
int RMQ[2][4 * SIZE];
int p[SIZE];
int idx[SIZE];
int N;

struct range {
  int m;
  int l;
  int r;
};

struct Cmp {
  bool operator()(range &a, range &b) { return a.m > b.m; }
};

int min(int a, int b) { return a < b ? a : b; }

int init(int node, int left, int right, int parity) {
  int &ret = RMQ[parity][node];
  if (left == right)
    return ret = ((left % 2) == parity ? p[left] : INF);
  int mid = (left + right) / 2;
  return ret = min(init(2 * node, left, mid, parity),
                   init(2 * node + 1, mid + 1, right, parity));
}

int query(int left, int right, int node, int nLeft, int nRight, int parity) {
  if (right < nLeft || nRight < left)
    return 987654321;
  if (left <= nLeft && nRight <= right)
    return RMQ[parity][node];
  int nMid = (nLeft + nRight) / 2;
  return min(query(left, right, 2 * node, nLeft, nMid, parity),
             query(left, right, 2 * node + 1, nMid + 1, nRight, parity));
}

int q(int left, int right, int parity) {
  if (left > right)
    return INF;
  return query(left, right, 1, 0, N - 1, parity);
}

int main() {
  int p1 = 0, p2 = 1;
  range tmp;
  scanf("%d", &N);
  for (int i = 0; i < N; i++) {
    scanf("%d", &p[i]);
    idx[p[i]] = i;
  }
  init(1, 0, N - 1, 0);
  init(1, 0, N - 1, 1);
  priority_queue<range, vector<range>, Cmp> pq;
  tmp.l = 0;
  tmp.r = N - 1;
  tmp.m = q(0, N - 1, 0);
  pq.push(tmp);
  while (!pq.empty()) {
    range now = pq.top();
    pq.pop();
    if (now.m == INF)
      continue;
    int second = q(idx[now.m] + 1, now.r, idx[now.m] % 2);
    printf("%d %d ", now.m, second);
    tmp.l = now.l;
    tmp.r = idx[now.m] - 1;
    if (tmp.l < tmp.r) {
      tmp.m = q(tmp.l, tmp.r, tmp.l % 2);
      pq.push(tmp);
    }
    tmp.l = idx[now.m] + 1;
    tmp.r = idx[second] - 1;
    if (tmp.l < tmp.r) {
      tmp.m = q(tmp.l, tmp.r, tmp.l % 2);
      pq.push(tmp);
    }
    tmp.l = idx[second] + 1;
    tmp.r = now.r;
    if (tmp.l < tmp.r) {
      tmp.m = q(tmp.l, tmp.r, tmp.l % 2);
      pq.push(tmp);
    }
  }
}

Fixed submission:
#include <algorithm>
#include <cstdio>
#include <queue>
using namespace std;

const int INF = 987654321;
const int SIZE = 200001;
int RMQ[2][4 * SIZE];
int p[SIZE];
int idx[SIZE];
int N;

struct range {
  int m;
  int l;
  int r;
};

struct Cmp {
  bool operator()(range &a, range &b) { return a.m > b.m; }
};

int min(int a, int b) { return a < b ? a : b; }

int init(int node, int left, int right, int parity) {
  int &ret = RMQ[parity][node];
  if (left == right)
    return ret = ((left % 2) == parity ? p[left] : INF);
  int mid = (left + right) / 2;
  return ret = min(init(2 * node, left, mid, parity),
                   init(2 * node + 1, mid + 1, right, parity));
}

int query(int left, int right, int node, int nLeft, int nRight, int parity) {
  if (right < nLeft || nRight < left)
    return 987654321;
  if (left <= nLeft && nRight <= right)
    return RMQ[parity][node];
  int nMid = (nLeft + nRight) / 2;
  return min(query(left, right, 2 * node, nLeft, nMid, parity),
             query(left, right, 2 * node + 1, nMid + 1, nRight, parity));
}

int q(int left, int right, int parity) {
  if (left > right)
    return INF;
  return query(left, right, 1, 0, N - 1, parity);
}

int main() {
  int p1 = 0, p2 = 1;
  range tmp;
  scanf("%d", &N);
  for (int i = 0; i < N; i++) {
    scanf("%d", &p[i]);
    idx[p[i]] = i;
  }
  init(1, 0, N - 1, 0);
  init(1, 0, N - 1, 1);
  priority_queue<range, vector<range>, Cmp> pq;
  tmp.l = 0;
  tmp.r = N - 1;
  tmp.m = q(0, N - 1, 0);
  pq.push(tmp);
  while (!pq.empty()) {
    range now = pq.top();
    pq.pop();
    if (now.m == INF)
      continue;
    int second = q(idx[now.m] + 1, now.r, (idx[now.m] + 1) % 2);
    printf("%d %d ", now.m, second);
    tmp.l = now.l;
    tmp.r = idx[now.m] - 1;
    if (tmp.l < tmp.r) {
      tmp.m = q(tmp.l, tmp.r, tmp.l % 2);
      pq.push(tmp);
    }
    tmp.l = idx[now.m] + 1;
    tmp.r = idx[second] - 1;
    if (tmp.l < tmp.r) {
      tmp.m = q(tmp.l, tmp.r, tmp.l % 2);
      pq.push(tmp);
    }
    tmp.l = idx[second] + 1;
    tmp.r = now.r;
    if (tmp.l < tmp.r) {
      tmp.m = q(tmp.l, tmp.r, tmp.l % 2);
      pq.push(tmp);
    }
  }
}