Problem p03641 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <bitset>
#include <cctype>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <utility>
#include <vector>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<int, char> pci;

const int kN = 1 << 17;

int p[kN];

struct SegmentTree {
  vector<pii> a;

  SegmentTree() : a(2 * kN - 1) {}

  void Set(int pos, pii x, int ind = 0, int tl = 0, int tr = kN - 1) {
    if (tl == tr) {
      a[ind] = x;
      return;
    }
    int tm = (tl + tr) >> 1;
    if (pos <= tm) {
      Set(pos, x, ind * 2 + 1, tl, tm);
    } else if (tm + 1 <= pos) {
      Set(pos, x, ind * 2 + 2, tm + 1, tr);
    }
    a[ind] = min(a[ind * 2 + 1], a[ind * 2 + 2]);
  }

  pii Rmq(int l, int r, int ind = 0, int tl = 0, int tr = kN - 1) {
    if (l == tl && r == tr) {
      return a[ind];
    }
    int tm = (tl + tr) >> 1;
    if (r <= tm) {
      return Rmq(l, r, ind * 2 + 1, tl, tm);
    } else if (tm + 1 <= l) {
      return Rmq(l, r, ind * 2 + 2, tm + 1, tr);
    } else {
      return min(Rmq(l, tm, ind * 2 + 1, tl, tm),
                 Rmq(tm + 1, r, ind * 2 + 2, tm + 1, tr));
    }
  }
};

const int kInf = 1e9;
vector<int> res;

SegmentTree odd, even;
set<tuple<pii, int, int>> pq;

pii GetMin(int l, int r) { return l & 1 ? odd.Rmq(l, r) : even.Rmq(l, r); }

bool Cmp(const pii &lhs, const pii &rhs) {
  return GetMin(lhs.first, lhs.second) < GetMin(rhs.first, rhs.second);
}

void Build(int l, int r) {
  if (r < l) {
    return;
  }
  SegmentTree &st = l & 1 ? odd : even;
  SegmentTree &st_r = l & 1 ? even : odd;
  pii mn = st.Rmq(l, r);
  pii mn_s = st_r.Rmq(mn.second + 1, r);
  res.push_back(mn.first);
  res.push_back(mn_s.first);
  vector<pii> arr;
  arr.emplace_back(l, mn.second - 1);
  arr.emplace_back(mn.second + 1, mn_s.second - 1);
  arr.emplace_back(mn_s.second + 1, r);
  sort(arr.begin(), arr.end(), Cmp);
  for (const auto &item : arr) {
    Build(item.first, item.second);
  }
}

int main() {
  std::ios_base::sync_with_stdio(false);
  int n;
  cin >> n;
  for (int i = 0; i < n; ++i) {
    cin >> p[i];
    if (i & 1) {
      odd.Set(i, make_pair(p[i], i));
      even.Set(i, make_pair(kInf, kInf));
    } else {
      even.Set(i, make_pair(p[i], i));
      odd.Set(i, make_pair(kInf, kInf));
    }
  }
  pq.insert(make_tuple(even.Rmq(0, n - 1), 0, n - 1));
  while (!pq.empty()) {
    const auto bg = *pq.begin();
    pq.erase(pq.begin());
    pii mn = get<0>(bg);
    int l = get<1>(bg);
    int r = get<2>(bg);
    auto &st = l & 1 ? odd : even;
    auto &st_r = l & 1 ? even : odd;
    pii mn_s = st_r.Rmq(mn.second + 1, r);
    res.push_back(mn.first);
    res.push_back(mn_s.first);
    if (l <= mn.second - 1) {
      pq.insert(make_tuple(GetMin(l, mn.second - 1), l, mn.second - 1));
    }
    if (mn.second + 1 <= mn_s.second - 1) {
      pq.insert(make_tuple(GetMin(mn.second + 1, mn_s.second - 1),
                           mn.second + 1, mn_s.second - 1));
    }
    if (mn_s.second + 1 <= r) {
      pq.insert(make_tuple(GetMin(mn_s.second + 1, r), mn_s.second + 1, r));
    }
  }
  for (int item : res) {
    cout << item << ' ';
  }
  cout << '\n';
  return 0;
}


Fixed submission:
#include <algorithm>
#include <bitset>
#include <cctype>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <utility>
#include <vector>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<int, char> pci;

const int kN = 1 << 18;

int p[kN];

struct SegmentTree {
  vector<pii> a;

  SegmentTree() : a(2 * kN - 1) {}

  void Set(int pos, pii x, int ind = 0, int tl = 0, int tr = kN - 1) {
    if (tl == tr) {
      a[ind] = x;
      return;
    }
    int tm = (tl + tr) >> 1;
    if (pos <= tm) {
      Set(pos, x, ind * 2 + 1, tl, tm);
    } else if (tm + 1 <= pos) {
      Set(pos, x, ind * 2 + 2, tm + 1, tr);
    }
    a[ind] = min(a[ind * 2 + 1], a[ind * 2 + 2]);
  }

  pii Rmq(int l, int r, int ind = 0, int tl = 0, int tr = kN - 1) {
    if (l == tl && r == tr) {
      return a[ind];
    }
    int tm = (tl + tr) >> 1;
    if (r <= tm) {
      return Rmq(l, r, ind * 2 + 1, tl, tm);
    } else if (tm + 1 <= l) {
      return Rmq(l, r, ind * 2 + 2, tm + 1, tr);
    } else {
      return min(Rmq(l, tm, ind * 2 + 1, tl, tm),
                 Rmq(tm + 1, r, ind * 2 + 2, tm + 1, tr));
    }
  }
};

const int kInf = 1e9;
vector<int> res;

SegmentTree odd, even;
set<tuple<pii, int, int>> pq;

pii GetMin(int l, int r) { return l & 1 ? odd.Rmq(l, r) : even.Rmq(l, r); }

bool Cmp(const pii &lhs, const pii &rhs) {
  return GetMin(lhs.first, lhs.second) < GetMin(rhs.first, rhs.second);
}

void Build(int l, int r) {
  if (r < l) {
    return;
  }
  SegmentTree &st = l & 1 ? odd : even;
  SegmentTree &st_r = l & 1 ? even : odd;
  pii mn = st.Rmq(l, r);
  pii mn_s = st_r.Rmq(mn.second + 1, r);
  res.push_back(mn.first);
  res.push_back(mn_s.first);
  vector<pii> arr;
  arr.emplace_back(l, mn.second - 1);
  arr.emplace_back(mn.second + 1, mn_s.second - 1);
  arr.emplace_back(mn_s.second + 1, r);
  sort(arr.begin(), arr.end(), Cmp);
  for (const auto &item : arr) {
    Build(item.first, item.second);
  }
}

int main() {
  std::ios_base::sync_with_stdio(false);
  int n;
  cin >> n;
  for (int i = 0; i < n; ++i) {
    cin >> p[i];
    if (i & 1) {
      odd.Set(i, make_pair(p[i], i));
      even.Set(i, make_pair(kInf, kInf));
    } else {
      even.Set(i, make_pair(p[i], i));
      odd.Set(i, make_pair(kInf, kInf));
    }
  }
  pq.insert(make_tuple(even.Rmq(0, n - 1), 0, n - 1));
  while (!pq.empty()) {
    const auto bg = *pq.begin();
    pq.erase(pq.begin());
    pii mn = get<0>(bg);
    int l = get<1>(bg);
    int r = get<2>(bg);
    auto &st = l & 1 ? odd : even;
    auto &st_r = l & 1 ? even : odd;
    pii mn_s = st_r.Rmq(mn.second + 1, r);
    res.push_back(mn.first);
    res.push_back(mn_s.first);
    if (l <= mn.second - 1) {
      pq.insert(make_tuple(GetMin(l, mn.second - 1), l, mn.second - 1));
    }
    if (mn.second + 1 <= mn_s.second - 1) {
      pq.insert(make_tuple(GetMin(mn.second + 1, mn_s.second - 1),
                           mn.second + 1, mn_s.second - 1));
    }
    if (mn_s.second + 1 <= r) {
      pq.insert(make_tuple(GetMin(mn_s.second + 1, r), mn_s.second + 1, r));
    }
  }
  for (int item : res) {
    cout << item << ' ';
  }
  cout << '\n';
  return 0;
}