Problem p03641 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>

const int MaxN = 200000;
const int INF = 0x7F7F7F7F;

struct data {
  int w, l, r;
  data(int _w = 0, int _l = 0, int _r = 0) { w = _w, l = _l, r = _r; }
  inline friend bool operator<(const data &x, const data &y) {
    return x.w > y.w;
  }
};

int N;
int A[MaxN + 5];
int B[MaxN + 5];
std::priority_queue<data> Pq;

template <const int Size> class sparse_table {
private:
  int value[Size + 5];
  int arr[20][Size + 5];
  int log2[Size + 5];

public:
  void init(int *a, int n) {
    for (int i = 2; i <= n; ++i)
      log2[i] = log2[i >> 1] + 1;
    for (int i = 1; i <= n; ++i) {
      value[i] = a[i];
      arr[0][i] = i;
    }
    for (int i = 1; (1 << i) <= n; ++i)
      for (int j = 1; j + (1 << i) - 1 <= n; ++j) {
        int vl = arr[i - 1][j], vr = arr[i - 1][j + (1 << (i - 1))];
        if (value[vl] < value[vr])
          arr[i][j] = vl;
        else
          arr[i][j] = vr;
      }
  }

  inline int query(int l, int r) {
    int k = log2[r - l + 1];
    int vl = arr[k][l], vr = arr[k][r - (1 << k) + 1];
    if (value[vl] < value[vr])
      return vl;
    else
      return vr;
  }
};
sparse_table<MaxN> St[2];

void init() {
  scanf("%d", &N);
  for (int i = 1; i <= N; ++i)
    scanf("%d", &A[i]);
}

void solve() {
  static int tmp[MaxN + 5];
  for (int i = 1; i <= N; ++i)
    if (i & 1)
      tmp[i] = A[i];
    else
      tmp[i] = INF;
  St[1].init(tmp, N);
  for (int i = 1; i <= N; ++i)
    if (i & 1)
      tmp[i] = INF;
    else
      tmp[i] = A[i];
  St[0].init(tmp, N);
  Pq.push(data(A[St[1].query(1, N)], 1, N));
  int cnt = 0;
  while (!Pq.empty()) {
    data d = Pq.top();
    // printf("d = (%d, %d, %d)\n", d.w, d.l, d.r);
    Pq.pop();
    int m1 = St[d.l & 1].query(d.l, d.r);
    int m2 = St[(m1 + 1) & 1].query(m1 + 1, d.r);
    B[++cnt] = A[m1];
    B[++cnt] = A[m2];
    if (d.l <= m1 - 1)
      Pq.push(data(A[St[d.l & 1].query(d.l, m1 - 1)], d.l, m1 - 1));
    if (m1 + 1 <= m2 - 1)
      Pq.push(data(A[St[(m1 + 1) & 1].query(m1 + 1, m2 - 1)], m1 + 1, m2 - 1));
    if (m2 + 1 <= d.r)
      Pq.push(data(A[St[(m2 + 1)].query(m2 + 1, d.r)], m2 + 1, d.r));
  }
  for (int i = 1; i <= N; ++i)
    printf("%d%c", B[i], " \n"[i == N]);
}

int main() {
  init();
  solve();
  return 0;
}

Fixed submission:
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>

const int MaxN = 200000;
const int INF = 0x7F7F7F7F;

struct data {
  int w, l, r;
  data(int _w = 0, int _l = 0, int _r = 0) { w = _w, l = _l, r = _r; }
  inline friend bool operator<(const data &x, const data &y) {
    return x.w > y.w;
  }
};

int N;
int A[MaxN + 5];
int B[MaxN + 5];
std::priority_queue<data> Pq;

template <const int Size> class sparse_table {
private:
  int value[Size + 5];
  int arr[20][Size + 5];
  int log2[Size + 5];

public:
  void init(int *a, int n) {
    for (int i = 2; i <= n; ++i)
      log2[i] = log2[i >> 1] + 1;
    for (int i = 1; i <= n; ++i) {
      value[i] = a[i];
      arr[0][i] = i;
    }
    for (int i = 1; (1 << i) <= n; ++i)
      for (int j = 1; j + (1 << i) - 1 <= n; ++j) {
        int vl = arr[i - 1][j], vr = arr[i - 1][j + (1 << (i - 1))];
        if (value[vl] < value[vr])
          arr[i][j] = vl;
        else
          arr[i][j] = vr;
      }
  }

  inline int query(int l, int r) {
    int k = log2[r - l + 1];
    int vl = arr[k][l], vr = arr[k][r - (1 << k) + 1];
    if (value[vl] < value[vr])
      return vl;
    else
      return vr;
  }
};
sparse_table<MaxN> St[2];

void init() {
  scanf("%d", &N);
  for (int i = 1; i <= N; ++i)
    scanf("%d", &A[i]);
}

void solve() {
  static int tmp[MaxN + 5];
  for (int i = 1; i <= N; ++i)
    if (i & 1)
      tmp[i] = A[i];
    else
      tmp[i] = INF;
  St[1].init(tmp, N);
  for (int i = 1; i <= N; ++i)
    if (i & 1)
      tmp[i] = INF;
    else
      tmp[i] = A[i];
  St[0].init(tmp, N);
  Pq.push(data(A[St[1].query(1, N)], 1, N));
  int cnt = 0;
  while (!Pq.empty()) {
    data d = Pq.top();
    // printf("d = (%d, %d, %d)\n", d.w, d.l, d.r);
    Pq.pop();
    int m1 = St[d.l & 1].query(d.l, d.r);
    int m2 = St[(m1 + 1) & 1].query(m1 + 1, d.r);
    B[++cnt] = A[m1];
    B[++cnt] = A[m2];
    if (d.l <= m1 - 1)
      Pq.push(data(A[St[d.l & 1].query(d.l, m1 - 1)], d.l, m1 - 1));
    if (m1 + 1 <= m2 - 1)
      Pq.push(data(A[St[(m1 + 1) & 1].query(m1 + 1, m2 - 1)], m1 + 1, m2 - 1));
    if (m2 + 1 <= d.r)
      Pq.push(data(A[St[(m2 + 1) & 1].query(m2 + 1, d.r)], m2 + 1, d.r));
  }
  for (int i = 1; i <= N; ++i)
    printf("%d%c", B[i], " \n"[i == N]);
}

int main() {
  init();
  solve();
  return 0;
}