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

#include <algorithm>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <tuple>
#include <vector>
using namespace std;

#define REP(i, p, n) for (ll i = p; i < ll(n); ++i)
#define rep(i, n) REP(i, 0, n)

using ll = long long int;
using pll = pair<ll, ll>;

template <typename T = int> struct SegmentTree {
  using u32 = unsigned int;
  u32 msb(u32 x) {
    u32 l = 0, r = 32, m = 0;
    while (l + 1 < r) {
      m = (l + r) >> 1;
      (x >> m ? l : r) = m;
    }
    return l;
  }

  vector<T> data;

  // 親子関係 => 親:(p-1)/2, 左:p*2+1, 右:p*2+2
  void init(int n, T v = 0) { data.assign((1 << (msb(n - 1) + 1)) * 2 - 1, v); }

  // ノード数
  inline int size() const { return (data.size() + 1) >> 1; }

  // 葉から木全体の値を更新する
  void add(int p, T x) {
    p += size() - 1;
    data[p] += x;

    while (p > 0) {
      p = (p - 1) >> 1;
      data[p] += x;
    }
  }

  // 二分木の構造を利用して区間の値を取得する
  T query(int a, int b) { return query(a, b, 0, 0, size()); }
  T query(int a, int b, int k, int l, int r) {
    if (r <= a || b <= l) {
      return 0;
    }
    if (a <= l && r <= b) {
      return data[k];
    }

    return query(a, b, (k << 1) + 1, l, (l + r) >> 1) +
           query(a, b, (k << 1) + 2, (l + r) >> 1, r);
  }
};

SegmentTree<> seg;

struct Query {
  ll ID, L, R;
};

int main() {
  ll N, Q;
  cin >> N >> Q;

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

  vector<Query> queries(Q);

  rep(i, Q) {
    auto &query = queries[i];
    query.ID = i;

    cin >> query.L >> query.R;
    --query.L;
    --query.R;
  }

  sort(queries.begin(), queries.end(),
       [](const auto &a, const auto &b) { return a.R < b.R; });

  vector<ll> last(N, -1);
  vector<ll> ans(Q);

  seg.init(N);

  ll index = 0;

  for (const auto &query : queries) {
    while (index <= query.R) {
      const auto c = C[index];
      if (last[c] != -1) {
        seg.add(last[c], -1);
      }

      last[c] = index;
      seg.add(index, 1);

      ++index;
    }

    const auto res = seg.query(query.L, query.R + 1);
    ans[query.ID] = res;
  }

  rep(i, Q) { cout << ans[i] << endl; }

  return 0;
}


Error: 0

Fixed submission:

#include <algorithm>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <tuple>
#include <vector>
using namespace std;

#define REP(i, p, n) for (ll i = p; i < ll(n); ++i)
#define rep(i, n) REP(i, 0, n)

using ll = long long int;
using pll = pair<ll, ll>;

struct BinaryIndexedTree {
  vector<ll> data;

  void init(ll n) { data.assign(n + 1, 0); }
  ll size() { return data.size(); }
  // 座標[p]の値を更新する, (p&-p)は最下位ビットを示す
  void add(ll p, ll x) {
    if (p != 0)
      for (ll i = p, n = size(); i <= n; i += (i & -i)) {
        data[i] += x;
      }
  }
  // 領域[0,p]の総和を求める
  ll sum(ll p) {
    ll res = 0;
    for (ll i = p; i > 0; i -= (i & -i)) {
      res += data[i];
    }
    return res;
  }
  // 領域[l,r]の総和を求める
  ll sum(ll l, ll r) { return sum(r) - (l ? sum(l - 1) : 0); }

} bit;

int main() {
  ll N, Q;
  cin >> N >> Q;

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

  using Section = tuple<ll, ll, ll>;
  vector<Section> LR(N);

  rep(i, Q) {
    cin >> get<0>(LR[i]) >> get<1>(LR[i]);
    get<2>(LR[i]) = i;
    --get<0>(LR[i]);
    --get<1>(LR[i]);
  }

  sort(LR.begin(), LR.end(),
       [](const auto &a, const auto &b) { return get<1>(a) < get<1>(b); });

  vector<ll> last(N, -1);
  vector<ll> ans(Q);

  bit.init(N);

  ll index = 0;

  for (const auto &lr : LR) {
    const auto lhs = get<0>(lr);
    const auto rhs = get<1>(lr);

    while (index <= rhs) {
      const auto c = C[index];
      if (last[c] != -1) {
        bit.add(last[c], -1);
      }

      last[c] = index;
      bit.add(index, 1);

      ++index;
    }

    const auto res = bit.sum(lhs, rhs);
    ans[get<2>(lr)] = res;
  }

  rep(i, Q) { cout << ans[i] << endl; }

  return 0;
}