Problem p02599 (C++) — buggy submission, verdict: Runtime Error

#include <algorithm>
#include <bitset>
#include <cmath>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <queue>
#include <set>
#include <tuple>
#include <vector>

using namespace std;

#define rep(i, n) for (int64_t i = 0; i < (int64_t)(n); i++)
#define irep(i, n) for (int64_t i = 0; i <= (int64_t)(n); i++)
#define rrep(i, n) for (int64_t i = (n)-1; i >= 0; i--)
#define rirep(i, n) for (int64_t i = n; i >= 0; i--)

#define chmax(a, b) (a) = max(a, b)
#define chmin(a, b) (a) = min(a, b)

template <typename T> class SegmentTree {
  const T unit;
  const function<T(const T &, const T &)> op;
  vector<T> container;

public:
  template <typename Op>
  SegmentTree(int size, const T &identity, const Op &operation)
      : unit(identity), op(operation), container(msb(size * 2 - 1)) {
    fill(container.begin(), container.end(), unit);
  }
  void update(size_t index, T value) {
    int n = container.size() / 2;
    container[index + n] = value;

    int node = (index + n) >> 1;
    while (node > 0) {
      container[node] = op(container[node << 1], container[(node << 1) + 1]);
      node >>= 1;
    }
  }
  T find(size_t s, size_t t) {
    if (s >= t) {
      return unit;
    }
    return find_inner(s, t, 0, container.size() / 2);
  }

private:
  T find_inner(size_t s, size_t t, size_t lb, size_t ub) {
    if (s == lb && t == ub) {
      int n = container.size() / 2;
      return container[lca(n + s, n + t - 1)];
    }

    T result = unit;
    size_t mid = (lb + ub) / 2;
    if (mid > s) {
      result = op(result, find_inner(s, min(mid, t), lb, mid));
    }
    if (mid < t) {
      result = op(result, find_inner(max(s, mid), t, mid, ub));
    }

    return result;
  }
  int lca(int n0, int n1) {
    int a = n0 ^ n1;
    return n0 / msb(a);
  }
  int msb(int x) {
    x |= x >> 1;
    x |= x >> 2;
    x |= x >> 4;
    x |= x >> 8;
    x |= x >> 16;

    return x + 1;
  }
};

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);

  int N, Q;
  cin >> N >> Q;

  vector<int> c(N);
  rep(i, N) {
    cin >> c[i];
    c[i]--;
  }

  using Query = tuple<int, int, int>;
  vector<Query> q;
  rep(i, Q) {
    int l, r;
    cin >> l >> r;
    q.push_back(Query(r, l, i));
  }
  sort(q.begin(), q.end());

  SegmentTree<int> cnt(N + 1, 0,
                       [](const int &lh, const int &rh) { return lh + rh; });
  vector<int> rightmost(N, 0);
  vector<int> result(Q);
  int j = 1;
  rep(i, Q) {
    int l, r, idx;
    tie(r, l, idx) = q[i];
    while (j <= r) {
      int old = rightmost[c[j - 1]];
      rightmost[c[j - 1]] = j;
      cnt.update(old, 0);
      cnt.update(j, 1);
      j++;
    }

    /*cerr << i << ": ";
    rep(k, N) { cerr << rightmost[k] << " "; }
    cerr << "\\n";
    cerr << "seg: ";
    irep(i, N) { cerr << cnt.find(i, i + 1) << " "; }
    cerr << "\\n";*/

    result[idx] = cnt.find(l, r + 1);
  }

  for (int r : result) {
    cout << r << "\\n";
  }
  return 0;
}

Error: 0

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cmath>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <queue>
#include <set>
#include <tuple>
#include <vector>

using namespace std;

#define rep(i, n) for (int64_t i = 0; i < (int64_t)(n); i++)
#define irep(i, n) for (int64_t i = 0; i <= (int64_t)(n); i++)
#define rrep(i, n) for (int64_t i = (n)-1; i >= 0; i--)
#define rirep(i, n) for (int64_t i = n; i >= 0; i--)

#define chmax(a, b) (a) = max(a, b)
#define chmin(a, b) (a) = min(a, b)

template <typename T> class SegmentTree {
  const T unit;
  const function<T(const T &, const T &)> op;
  vector<T> container;

public:
  template <typename Op>
  SegmentTree(int size, const T &identity, const Op &operation)
      : unit(identity), op(operation), container(msb(size * 2 - 1)) {
    fill(container.begin(), container.end(), unit);
  }
  void update(size_t index, T value) {
    int n = container.size() / 2;
    container[index + n] = value;

    int node = (index + n) >> 1;
    while (node > 0) {
      container[node] = op(container[node << 1], container[(node << 1) + 1]);
      node >>= 1;
    }
  }
  T find(size_t s, size_t t) {
    if (s >= t) {
      return unit;
    }
    return find_inner(s, t, 0, container.size() / 2);
  }

private:
  T find_inner(size_t s, size_t t, size_t lb, size_t ub) {
    if (s == lb && t == ub) {
      int n = container.size() / 2;
      return container[lca(n + s, n + t - 1)];
    }

    T result = unit;
    size_t mid = (lb + ub) / 2;
    if (mid > s) {
      result = op(result, find_inner(s, min(mid, t), lb, mid));
    }
    if (mid < t) {
      result = op(result, find_inner(max(s, mid), t, mid, ub));
    }

    return result;
  }
  int lca(int n0, int n1) {
    int a = n0 ^ n1;
    return n0 / msb(a);
  }
  int msb(int x) {
    x |= x >> 1;
    x |= x >> 2;
    x |= x >> 4;
    x |= x >> 8;
    x |= x >> 16;

    return x + 1;
  }
};

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);

  int N, Q;
  cin >> N >> Q;

  if (N == 1) {
    throw string("hoge");
  }

  vector<int> c(N);
  rep(i, N) {
    cin >> c[i];
    c[i]--;
  }

  using Query = tuple<int, int, int>;
  vector<Query> q;
  rep(i, Q) {
    int l, r;
    cin >> l >> r;
    q.push_back(Query(r, l, i));
  }
  sort(q.begin(), q.end());

  SegmentTree<int> cnt(N + 1, 0,
                       [](const int &lh, const int &rh) { return lh + rh; });
  vector<int> rightmost(N, 0);
  vector<int> result(N);
  int j = 1;
  rep(i, Q) {
    int l, r, idx;
    tie(r, l, idx) = q[i];
    while (j <= r) {
      int old = rightmost[c[j - 1]];
      rightmost[c[j - 1]] = j;
      cnt.update(old, 0);
      cnt.update(j, 1);
      j++;
    }

    /*cerr << i << ": ";
    rep(k, N) { cerr << rightmost[k] << " "; }
    cerr << "\\n";
    cerr << "seg: ";
    irep(i, N) { cerr << cnt.find(i, i + 1) << " "; }
    cerr << "\\n";*/

    result[idx] = cnt.find(l, r + 1);
  }

  rep(i, Q) { cout << result[i] << "\\n"; }
  return 0;
}