Problem p03641 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <map>
#include <queue>
#include <utility>
#include <vector>
using std::map;
using std::pair;
#define mp std::make_pair
#define inf 200005
const int maxn = 1e5 + 5;
int n;
int a[maxn];
int st[2][maxn][20];
map<pair<int, int>, pair<int, int>> son[3];
int value[maxn], cnt;
struct cmp {
  bool operator()(pair<int, int> x, pair<int, int> y) const {
    if (a[x.first] == a[y.first])
      return a[x.second] > a[y.second];
    return a[x.first] > a[y.first];
  }
};

std::priority_queue<pair<int, int>, std::vector<pair<int, int>>, cmp> pq;
int rmq(int k, int l, int r) {
  if (l > r)
    return 0;
  int len = floor(log(r - l + 1) / (log(2)));
  if (a[st[k][l][len]] < a[st[k][r - (1 << len) + 1][len]])
    return st[k][l][len];
  else
    return st[k][r - (1 << len) + 1][len];
}
void set(pair<int, int> &a, pair<int, int> b) {
  a.first = b.first;
  a.second = b.second;
}
pair<int, int> divide(int k, int l, int r) {
  if (l > r)
    return mp(-1, -1);
  int pos1 = rmq(k, l, r);
  int pos2 = rmq(k ^ 1, pos1 + 1, r);
  set(son[0][mp(pos1, pos2)], divide(l & 1 ? 0 : 1, l, pos1 - 1));
  set(son[1][mp(pos1, pos2)],
      divide((pos1 + 1) & 1 ? 0 : 1, pos1 + 1, pos2 - 1));
  set(son[2][mp(pos1, pos2)], divide((pos2 + 1) & 1 ? 0 : 1, pos2 + 1, r));
  return mp(pos1, pos2);
}
void dfs(int x, int y) {
  pq.pop();
  printf("%d %d ", a[x], a[y]);
  for (int i = 0; i < 3; i++)
    if (son[i][mp(x, y)].first != -1)
      pq.push(son[i][mp(x, y)]);
  if (!pq.empty())
    dfs(pq.top().first, pq.top().second);
}
int main() {
#ifdef orz
  freopen("input", "r", stdin);
#endif
  scanf("%d", &n);
  for (int i = 1; i <= n; i++)
    scanf("%d", &a[i]);
  a[0] = inf;
  for (int i = 1; i <= n; i += 2)
    st[0][i][0] = i, st[1][i][0] = st[0][i + 1][0] = 0, st[1][i + 1][0] = i + 1;
  for (int j = 1; j <= 17; j++) {
    for (int i = 1; i <= n; i++) {
      if (a[st[0][i][j - 1]] < a[st[0][i + (1 << (j - 1))][j - 1]])
        st[0][i][j] = st[0][i][j - 1];
      else
        st[0][i][j] = st[0][i + (1 << (j - 1))][j - 1];
      if (a[st[1][i][j - 1]] < a[st[1][i + (1 << (j - 1))][j - 1]])
        st[1][i][j] = st[1][i][j - 1];
      else
        st[1][i][j] = st[1][i + (1 << (j - 1))][j - 1];
    }
  }
  pair<int, int> rt = divide(0, 1, n);
  pq.push(rt);
  dfs(rt.first, rt.second);
}


Fixed submission:
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <map>
#include <queue>
#include <utility>
#include <vector>
using std::map;
using std::pair;
#define mp std::make_pair
#define inf 200005
const int maxn = 4e5 + 5;
int n;
int a[maxn];
int st[2][maxn][20];
map<pair<int, int>, pair<int, int>> son[3];
int value[maxn], cnt;
struct cmp {
  bool operator()(pair<int, int> x, pair<int, int> y) const {
    if (a[x.first] == a[y.first])
      return a[x.second] > a[y.second];
    return a[x.first] > a[y.first];
  }
};

std::priority_queue<pair<int, int>, std::vector<pair<int, int>>, cmp> pq;
int rmq(int k, int l, int r) {
  if (l > r)
    return 0;
  int len = floor(log(r - l + 1) / (log(2)));
  if (a[st[k][l][len]] < a[st[k][r - (1 << len) + 1][len]])
    return st[k][l][len];
  else
    return st[k][r - (1 << len) + 1][len];
}
void set(pair<int, int> &a, pair<int, int> b) {
  a.first = b.first;
  a.second = b.second;
}
pair<int, int> divide(int k, int l, int r) {
  if (l > r)
    return mp(-1, -1);
  int pos1 = rmq(k, l, r);
  int pos2 = rmq(k ^ 1, pos1 + 1, r);
  set(son[0][mp(pos1, pos2)], divide(l & 1 ? 0 : 1, l, pos1 - 1));
  set(son[1][mp(pos1, pos2)],
      divide((pos1 + 1) & 1 ? 0 : 1, pos1 + 1, pos2 - 1));
  set(son[2][mp(pos1, pos2)], divide((pos2 + 1) & 1 ? 0 : 1, pos2 + 1, r));
  return mp(pos1, pos2);
}
void dfs(int x, int y) {
  pq.pop();
  printf("%d %d ", a[x], a[y]);
  for (int i = 0; i < 3; i++)
    if (son[i][mp(x, y)].first != -1)
      pq.push(son[i][mp(x, y)]);
  if (!pq.empty())
    dfs(pq.top().first, pq.top().second);
}
int main() {
#ifdef orz
  freopen("input", "r", stdin);
#endif
  scanf("%d", &n);
  for (int i = 1; i <= n; i++)
    scanf("%d", &a[i]);
  a[0] = inf;
  for (int i = 1; i <= n; i += 2)
    st[0][i][0] = i, st[1][i][0] = st[0][i + 1][0] = 0, st[1][i + 1][0] = i + 1;
  for (int j = 1; j <= 17; j++) {
    for (int i = 1; i <= n; i++) {
      if (a[st[0][i][j - 1]] < a[st[0][i + (1 << (j - 1))][j - 1]])
        st[0][i][j] = st[0][i][j - 1];
      else
        st[0][i][j] = st[0][i + (1 << (j - 1))][j - 1];
      if (a[st[1][i][j - 1]] < a[st[1][i + (1 << (j - 1))][j - 1]])
        st[1][i][j] = st[1][i][j - 1];
      else
        st[1][i][j] = st[1][i + (1 << (j - 1))][j - 1];
    }
  }
  pair<int, int> rt = divide(0, 1, n);
  pq.push(rt);
  dfs(rt.first, rt.second);
}