Problem p03641 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>

using namespace std;

const int MAXN = 2E5;
const int LOGN = 18;
int p[MAXN];
int minTable1[LOGN + 1][MAXN];
int minTable2[LOGN + 1][MAXN];
vector<pair<int, int>> ans;
int pos[MAXN];
priority_queue<tuple<int, int, int, int>, vector<tuple<int, int, int, int>>,
               greater<tuple<int, int, int, int>>>
    pq;

pair<int, int> query(int l, int r) {
  int len = r - l + 1;
  int k = 31 - __builtin_clz(len);
  int mid = l + (len - (1 << k));
  return make_pair(min(minTable1[k][l], minTable1[k][mid]),
                   min(minTable2[k][l], minTable2[k][mid]));
}

pair<int, int> get(int l, int r) {
  int small = -1;
  int nextSmall = -1;
  int pos1 = -1;
  if (l % 2 == 0) {
    small = query(l, r).first;
    pos1 = pos[small];
    nextSmall = query(pos1 + 1, r).second;
  } else {
    small = query(l, r).second;
    pos1 = pos[small];
    nextSmall = query(pos1 + 1, r).first;
  }
  return make_pair(small, nextSmall);
}

void push(int l, int r) {
  if (l > r)
    return;
  pair<int, int> pr = get(l, r);
  pq.push(make_tuple(pr.first, pr.second, l, r));
}

int main() {
  int n;
  cin >> n;
  ans.reserve(n / 2);
  fill(minTable1[0], minTable1[0] + n, n + 1);
  fill(minTable2[0], minTable2[0] + n, n + 1);
  for (int i = 0; i < n; i++) {
    cin >> p[i];
    pos[p[i]] = i;
    if (i % 2 == 0)
      minTable1[0][i] = p[i];
    else
      minTable2[0][i] = p[i];
  }
  for (int i = 1; i <= LOGN; i++) {
    for (int j = 0; j < n; j++) {
      int inc = (1 << (i - 1));
      minTable1[i][j] =
          min(minTable1[i - 1][j], minTable1[i - 1][min(n - 1, j + inc)]);
      minTable2[i][j] =
          min(minTable2[i - 1][j], minTable2[i - 1][min(n - 1, j + inc)]);
    }
  }
  pair<int, int> first = get(0, n - 1);
  pq.push(make_tuple(first.first, first.second, 0, n - 1));
  while (!pq.empty()) {
    tuple<int, int, int, int> t = pq.top();
    pq.pop();
    int s1 = get<0>(t);
    int s2 = get<1>(t);
    int l = get<2>(t);
    int r = get<3>(t);
    ans.push_back(make_pair(s1, s2));
    push(l, pos[s1] - 1);
    push(pos[s1] + 1, pos[s2] - 1);
    push(pos[s2] + 1, r);
  }
  for (pair<int, int> pr : ans) {
    cout << pr.first << " " << pr.second << " ";
  }
  cout << endl;
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>

using namespace std;

const int MAXN = 2E5;
const int LOGN = 18;
int p[MAXN];
int minTable1[LOGN + 1][MAXN];
int minTable2[LOGN + 1][MAXN];
vector<pair<int, int>> ans;
int pos[MAXN + 1];
priority_queue<tuple<int, int, int, int>, vector<tuple<int, int, int, int>>,
               greater<tuple<int, int, int, int>>>
    pq;

pair<int, int> query(int l, int r) {
  int len = r - l + 1;
  int k = 31 - __builtin_clz(len);
  int mid = l + (len - (1 << k));
  return make_pair(min(minTable1[k][l], minTable1[k][mid]),
                   min(minTable2[k][l], minTable2[k][mid]));
}

pair<int, int> get(int l, int r) {
  int small = -1;
  int nextSmall = -1;
  int pos1 = -1;
  if (l % 2 == 0) {
    small = query(l, r).first;
    pos1 = pos[small];
    nextSmall = query(pos1 + 1, r).second;
  } else {
    small = query(l, r).second;
    pos1 = pos[small];
    nextSmall = query(pos1 + 1, r).first;
  }
  return make_pair(small, nextSmall);
}

void push(int l, int r) {
  if (l > r)
    return;
  pair<int, int> pr = get(l, r);
  pq.push(make_tuple(pr.first, pr.second, l, r));
}

int main() {
  int n;
  cin >> n;
  ans.reserve(n / 2);
  fill(minTable1[0], minTable1[0] + n, n + 1);
  fill(minTable2[0], minTable2[0] + n, n + 1);
  for (int i = 0; i < n; i++) {
    cin >> p[i];
    pos[p[i]] = i;
    if (i % 2 == 0)
      minTable1[0][i] = p[i];
    else
      minTable2[0][i] = p[i];
  }
  for (int i = 1; i <= LOGN; i++) {
    for (int j = 0; j < n; j++) {
      int inc = (1 << (i - 1));
      minTable1[i][j] =
          min(minTable1[i - 1][j], minTable1[i - 1][min(n - 1, j + inc)]);
      minTable2[i][j] =
          min(minTable2[i - 1][j], minTable2[i - 1][min(n - 1, j + inc)]);
    }
  }
  pair<int, int> first = get(0, n - 1);
  pq.push(make_tuple(first.first, first.second, 0, n - 1));
  while (!pq.empty()) {
    tuple<int, int, int, int> t = pq.top();
    pq.pop();
    int s1 = get<0>(t);
    int s2 = get<1>(t);
    int l = get<2>(t);
    int r = get<3>(t);
    ans.push_back(make_pair(s1, s2));
    push(l, pos[s1] - 1);
    push(pos[s1] + 1, pos[s2] - 1);
    push(pos[s2] + 1, r);
  }
  for (pair<int, int> pr : ans) {
    cout << pr.first << " " << pr.second << " ";
  }
  cout << endl;
  return 0;
}