Problem p03641 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const int MAX = 1 << 16;
const int INF = 0x3f3f3f3f;
int N, p[2 * MAX], seg[2][2 * MAX], invp[2 * MAX], ans[2 * MAX], anscnt;
int build(int *arr, int x) {
  if (x >= MAX) {
    if (x - MAX < N / 2)
      return arr[x];
    return INF;
  }
  return arr[x] = min(build(arr, x * 2), build(arr, x * 2 + 1));
}
int find_min(int *arr, int x, int y, int a, int b, int p) {
  if (x <= a && b <= y)
    return arr[p];
  if (x >= b || y <= a)
    return INF;
  return min(find_min(arr, x, y, a, (a + b) / 2, 2 * p),
             find_min(arr, x, y, (a + b) / 2, b, 2 * p + 1));
}
struct range {
  int x, y;
  int r_min1, r_min2, r_idx1, r_idx2;
  void r_gen(int a, int b) {
    x = a, y = b;
    if (a >= b)
      return;
    r_min1 = find_min(seg[x % 2], x / 2, y / 2, 0, MAX, 1);
    r_idx1 = invp[r_min1];
    // printf("%d %d %d %d %d %d\n",x,y,r_min1,r_idx1,(r_idx1+1)/2,(y+1)/2);
    r_min2 = find_min(seg[!(x % 2)], (r_idx1 + 1) / 2, (y + 1) / 2, 0, MAX, 1);
    r_idx2 = invp[r_min2];
  }
  bool operator<(const range &a) const { return r_min1 > a.r_min1; }
};
priority_queue<range> atl;
int main() {
  range tmp;
  scanf("%d", &N);
  for (int i = 0; i < N; i++)
    scanf("%d", &p[i]), invp[p[i]] = i;
  for (int i = 0; i < N; i++)
    seg[i % 2][MAX + i / 2] = p[i];
  build(seg[0], 1), build(seg[1], 1);
  tmp.r_gen(0, N);
  atl.push(tmp);
  while (!atl.empty()) {
    range t = atl.top();
    atl.pop();
    if (t.y > t.x) {
      ans[anscnt++] = t.r_min1;
      ans[anscnt++] = t.r_min2;
      tmp.r_gen(t.x, t.r_idx1);
      atl.push(tmp);
      tmp.r_gen(t.r_idx1 + 1, t.r_idx2);
      atl.push(tmp);
      tmp.r_gen(t.r_idx2 + 1, t.y);
      atl.push(tmp);
    }
  }
  for (int i = 0; i < N; i++)
    printf("%d ", ans[i]);
  printf("\n");
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const int MAX = 1 << 17;
const int INF = 0x3f3f3f3f;
int N, p[2 * MAX], seg[2][2 * MAX], invp[2 * MAX], ans[2 * MAX], anscnt;
int build(int *arr, int x) {
  if (x >= MAX) {
    if (x - MAX < N / 2)
      return arr[x];
    return INF;
  }
  return arr[x] = min(build(arr, x * 2), build(arr, x * 2 + 1));
}
int find_min(int *arr, int x, int y, int a, int b, int p) {
  if (x <= a && b <= y)
    return arr[p];
  if (x >= b || y <= a)
    return INF;
  return min(find_min(arr, x, y, a, (a + b) / 2, 2 * p),
             find_min(arr, x, y, (a + b) / 2, b, 2 * p + 1));
}
struct range {
  int x, y;
  int r_min1, r_min2, r_idx1, r_idx2;
  void r_gen(int a, int b) {
    x = a, y = b;
    if (a >= b)
      return;
    r_min1 = find_min(seg[x % 2], x / 2, y / 2, 0, MAX, 1);
    r_idx1 = invp[r_min1];
    // printf("%d %d %d %d %d %d\n",x,y,r_min1,r_idx1,(r_idx1+1)/2,(y+1)/2);
    r_min2 = find_min(seg[!(x % 2)], (r_idx1 + 1) / 2, (y + 1) / 2, 0, MAX, 1);
    r_idx2 = invp[r_min2];
  }
  bool operator<(const range &a) const { return r_min1 > a.r_min1; }
};
priority_queue<range> atl;
int main() {
  range tmp;
  scanf("%d", &N);
  for (int i = 0; i < N; i++)
    scanf("%d", &p[i]), invp[p[i]] = i;
  for (int i = 0; i < N; i++)
    seg[i % 2][MAX + i / 2] = p[i];
  build(seg[0], 1), build(seg[1], 1);
  tmp.r_gen(0, N);
  atl.push(tmp);
  while (!atl.empty()) {
    range t = atl.top();
    atl.pop();
    if (t.y > t.x) {
      ans[anscnt++] = t.r_min1;
      ans[anscnt++] = t.r_min2;
      tmp.r_gen(t.x, t.r_idx1);
      atl.push(tmp);
      tmp.r_gen(t.r_idx1 + 1, t.r_idx2);
      atl.push(tmp);
      tmp.r_gen(t.r_idx2 + 1, t.y);
      atl.push(tmp);
    }
  }
  for (int i = 0; i < N; i++)
    printf("%d ", ans[i]);
  printf("\n");
}