Problem p03295 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cfloat>
#include <complex>
#include <functional>
#include <iostream>
#include <limits.h>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <unordered_map>
#include <vector>

#define fs first
#define sc second

using namespace std;

typedef long long ll;
typedef pair<ll, ll> P;

#define MAX_N 110000

template <typename T> class SegTree {
public:
  int n;
  T dat[2 * MAX_N - 1];

  void init(int n_, T init_num) {
    n = 1;
    while (n < n_)
      n *= 2;
    for (int i = 0; i < 2 * n - 1; i++) {
      dat[i] = init_num;
    }
  }

  // k番目の値(0-indexed)をaに変更
  void update(int k, T a) {
    k += n - 1;
    dat[k] = a;
    while (k > 0) {
      k = (k - 1) / 2;
      dat[k] = min(dat[k * 2 + 1], dat[k * 2 + 2]);
    }
  }

  // [a, b)の最小値を求める。
  // kは節点の番号、l, rはその節点が[l, r)に対応づいていることを表す。
  // query(a, b, 0, 0, n)で外からは呼び出す。
  ll query(int a, int b, int k, int l, int r) {
    if (r <= a || b <= l) {
      return MAX_N + 1;
    }

    if (a <= l && r <= b) {
      return dat[k];
    } else {
      ll vl = query(a, b, k * 2 + 1, l, (l + r) / 2);
      ll vr = query(a, b, k * 2 + 2, (l + r) / 2, r);
      return min(vl, vr);
    }
  }
};

int main() {
  int n, m;
  cin >> n >> m;

  SegTree<int> st;
  st.init(n + 1, MAX_N + 1);

  for (int i = 0; i < m; i++) {
    int a, b;
    cin >> a >> b;
    a--;
    b--;
    int q = st.query(a, a + 1, 0, 0, st.n);
    if (b < q) {
      st.update(a, b);
    }
  }

  int res = 0;
  int x = 0;
  while (x < n) {
    int q = st.query(x, n + 1, 0, 0, st.n);
    if (q == MAX_N + 1) {
      break;
    }
    res++;
    x = q;
  }

  cout << res << endl;

  return 0;
}


Fixed submission:
#include <algorithm>
#include <cfloat>
#include <complex>
#include <functional>
#include <iostream>
#include <limits.h>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <unordered_map>
#include <vector>

#define fs first
#define sc second

using namespace std;

typedef long long ll;
typedef pair<ll, ll> P;

#define MAX_N 210000

template <typename T> class SegTree {
public:
  int n;
  T dat[2 * MAX_N - 1];

  void init(int n_, T init_num) {
    n = 1;
    while (n < n_)
      n *= 2;
    for (int i = 0; i < 2 * n - 1; i++) {
      dat[i] = init_num;
    }
  }

  // k番目の値(0-indexed)をaに変更
  void update(int k, T a) {
    k += n - 1;
    dat[k] = a;
    while (k > 0) {
      k = (k - 1) / 2;
      dat[k] = min(dat[k * 2 + 1], dat[k * 2 + 2]);
    }
  }

  // [a, b)の最小値を求める。
  // kは節点の番号、l, rはその節点が[l, r)に対応づいていることを表す。
  // query(a, b, 0, 0, n)で外からは呼び出す。
  ll query(int a, int b, int k, int l, int r) {
    if (r <= a || b <= l) {
      return MAX_N + 1;
    }

    if (a <= l && r <= b) {
      return dat[k];
    } else {
      ll vl = query(a, b, k * 2 + 1, l, (l + r) / 2);
      ll vr = query(a, b, k * 2 + 2, (l + r) / 2, r);
      return min(vl, vr);
    }
  }
};

int main() {
  int n, m;
  cin >> n >> m;

  SegTree<int> st;
  st.init(n + 1, MAX_N + 1);

  for (int i = 0; i < m; i++) {
    int a, b;
    cin >> a >> b;
    a--;
    b--;
    int q = st.query(a, a + 1, 0, 0, st.n);
    if (b < q) {
      st.update(a, b);
    }
  }

  int res = 0;
  int x = 0;
  while (x < n) {
    int q = st.query(x, n + 1, 0, 0, st.n);
    if (q == MAX_N + 1) {
      break;
    }
    res++;
    x = q;
  }

  cout << res << endl;

  return 0;
}