Problem p03641 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
#define ls (n << 1)
#define rs ((n << 1) | 1)
using namespace std;

struct node {
  int l, r, x, y;
};
int n, a[100010], b[100010], t[2][200010];
set<node> S;

bool operator<(node x, node y) { return a[x.x] < a[y.x]; }

void build(int op, int n, int l, int r) {
  if (l == r)
    t[op][n] = a[2 * l - op];
  else {
    int mid = (l + r) >> 1;
    build(op, ls, l, mid), build(op, rs, mid + 1, r);
    t[op][n] = min(t[op][ls], t[op][rs]);
  }
}

int ask(int op, int n, int l, int r, int L, int R) {
  if ((L <= l) && (r <= R))
    return t[op][n];
  else {
    int mid = (l + r) >> 1;
    if (mid >= R)
      return ask(op, ls, l, mid, L, R);
    if (L > mid)
      return ask(op, rs, mid + 1, r, L, R);
    return min(ask(op, ls, l, mid, L, R), ask(op, rs, mid + 1, r, L, R));
  }
}

void doit(int l, int r) {
  int x, y;
  if (l & 1) {
    x = b[ask(1, 1, 1, n / 2, l / 2 + 1, r / 2)],
    y = b[ask(0, 1, 1, n / 2, x / 2 + 1, r / 2)];
  } else {
    x = b[ask(0, 1, 1, n / 2, l / 2, r / 2)],
    y = b[ask(1, 1, 1, n / 2, x / 2 + 1, r / 2 + 1)];
  }
  S.insert((node){l, r, x, y});
}

void work() {
  scanf("%d", &n);
  for (int i = 1; i <= n; i++)
    scanf("%d", &a[i]), b[a[i]] = i;
  build(0, 1, 1, n / 2), build(1, 1, 1, n / 2);
  int x = b[ask(1, 1, 1, n / 2, 1, n / 2)],
      y = b[ask(0, 1, 1, n / 2, x / 2 + 1, n / 2)];
  S.insert((node){1, n, x, y});
  for (node p; S.size();) {
    p = *S.begin(), S.erase(S.begin());
    printf("%d %d ", a[p.x], a[p.y]);
    if (p.l != p.x)
      doit(p.l, p.x - 1);
    if (p.x + 1 != p.y)
      doit(p.x + 1, p.y - 1);
    if (p.y != p.r)
      doit(p.y + 1, p.r);
  }
}

int main() {
  work();
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
#define ls (n << 1)
#define rs ((n << 1) | 1)
using namespace std;

struct node {
  int l, r, x, y;
};
int n, a[200010], b[200010], t[2][400010];
set<node> S;

bool operator<(node x, node y) { return a[x.x] < a[y.x]; }

void build(int op, int n, int l, int r) {
  if (l == r)
    t[op][n] = a[2 * l - op];
  else {
    int mid = (l + r) >> 1;
    build(op, ls, l, mid), build(op, rs, mid + 1, r);
    t[op][n] = min(t[op][ls], t[op][rs]);
  }
}

int ask(int op, int n, int l, int r, int L, int R) {
  if ((L <= l) && (r <= R))
    return t[op][n];
  else {
    int mid = (l + r) >> 1;
    if (mid >= R)
      return ask(op, ls, l, mid, L, R);
    if (L > mid)
      return ask(op, rs, mid + 1, r, L, R);
    return min(ask(op, ls, l, mid, L, R), ask(op, rs, mid + 1, r, L, R));
  }
}

void doit(int l, int r) {
  int x, y;
  if (l & 1) {
    x = b[ask(1, 1, 1, n / 2, l / 2 + 1, r / 2)],
    y = b[ask(0, 1, 1, n / 2, x / 2 + 1, r / 2)];
  } else {
    x = b[ask(0, 1, 1, n / 2, l / 2, r / 2)],
    y = b[ask(1, 1, 1, n / 2, x / 2 + 1, r / 2 + 1)];
  }
  S.insert((node){l, r, x, y});
}

void work() {
  scanf("%d", &n);
  for (int i = 1; i <= n; i++)
    scanf("%d", &a[i]), b[a[i]] = i;
  build(0, 1, 1, n / 2), build(1, 1, 1, n / 2);
  int x = b[ask(1, 1, 1, n / 2, 1, n / 2)],
      y = b[ask(0, 1, 1, n / 2, x / 2 + 1, n / 2)];
  S.insert((node){1, n, x, y});
  for (node p; S.size();) {
    p = *S.begin(), S.erase(S.begin());
    printf("%d %d ", a[p.x], a[p.y]);
    if (p.l != p.x)
      doit(p.l, p.x - 1);
    if (p.x + 1 != p.y)
      doit(p.x + 1, p.y - 1);
    if (p.y != p.r)
      doit(p.y + 1, p.r);
  }
}

int main() {
  work();
  return 0;
}