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

#include "bits/stdc++.h"
using namespace std;
// #define int long long
#define REP(i, n) for (int i = 0; i < (int)n; ++i)
#define RREP(i, n) for (int i = (int)n - 1; i >= 0; --i)
#define FOR(i, s, n) for (int i = s; i < (int)n; ++i)
#define RFOR(i, s, n) for (int i = (int)n - 1; i >= s; --i)
#define ALL(a) a.begin(), a.end()
#define IN(a, x, b) (a <= x && x < b)
template <class T> istream &operator>>(istream &is, vector<T> &vec) {
  for (T &x : vec)
    is >> x;
  return is;
}
template <class T> inline void out(T t) { cout << t << "\\n"; }
template <class T, class... Ts> inline void out(T t, Ts... ts) {
  cout << t << " ";
  out(ts...);
}
template <class T> inline bool CHMIN(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> inline bool CHMAX(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}

#define endl '\\n'
#define IOS()                                                                  \\
  ios_base::sync_with_stdio(0);                                                \\
  cin.tie(0)

// insert→solveでansに全クエリに対する結果が格納
// add,del を変更していろいろなクエリに対応する
// 以下は区間内の数の種類数についてのクエリが飛んでくる場合

// 現在の状態および値
const int MAX_VAL = 500050;
int a[MAX_VAL];   // 要素
int cnt[MAX_VAL]; // 区間内のiの個数
int res;          // 区間内の種類の数

class Mo {
private:
  vector<int> left, right;
  const int width;
  void add(const int id);
  void del(const int id);

public:
  vector<int> ans;

  Mo(const int n) : width((int)sqrt(n)) {}
  // クエリ[l,r)
  void insert(const int l, const int r) {
    left.push_back(l), right.push_back(r);
  }
  void solve() {
    const int sz = (int)left.size();
    int nl = 0, nr = 0;
    vector<int> ord(sz);
    iota(ord.begin(), ord.end(), 0);
    sort(ord.begin(), ord.end(), [&](const int a, const int b) {
      const int c = left[a] / width, d = left[b] / width;
      return (c == d)
                 ? ((c & 1) ? (right[b] < right[a]) : (right[a] < right[b]))
                 : (c < d);
    });
    ans.resize(sz);
    for (const int id : ord) {
      while (nl > left[id])
        add(--nl);
      while (nr < right[id])
        add(nr++); // add
      while (nl < left[id])
        del(nl++);
      while (nr > right[id])
        del(--nr); // del
      ans[id] = res;
    }
  }
};

// idは元の配列のインデックス
void Mo::add(const int id) {
  if (cnt[a[id]] == 0) {
    // cnt[a[id]]++;
    res++;
  }
  cnt[a[id]]++;
}

void Mo::del(const int id) {
  if (cnt[a[id]] == 1) {
    // cnt[a[id]]--;
    res--;
  }
  cnt[a[id]]--;
}

int main() {
  IOS();
  int N, Q;
  cin >> N >> Q;
  for (int i = 0; i < N; i++) {
    cin >> a[i];
    --a[i];
  }
  Mo mo(N);
  for (int i = 0; i < Q; i++) {
    int l, r;
    cin >> l >> r;
    mo.insert(--l, r);
  }
  mo.solve();
  for (int i = 0; i < Q; i++) {
    cout << mo.ans[i] << "\\n";
  }
}


Error: 0

Fixed submission:

#include "bits/stdc++.h"
using namespace std;
// #define int long long
#define REP(i, n) for (int i = 0; i < (int)n; ++i)
#define RREP(i, n) for (int i = (int)n - 1; i >= 0; --i)
#define FOR(i, s, n) for (int i = s; i < (int)n; ++i)
#define RFOR(i, s, n) for (int i = (int)n - 1; i >= s; --i)
#define ALL(a) a.begin(), a.end()
#define IN(a, x, b) (a <= x && x < b)
template <class T> istream &operator>>(istream &is, vector<T> &vec) {
  for (T &x : vec)
    is >> x;
  return is;
}
template <class T> inline void out(T t) { cout << t << "\\n"; }
template <class T, class... Ts> inline void out(T t, Ts... ts) {
  cout << t << " ";
  out(ts...);
}
template <class T> inline bool CHMIN(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> inline bool CHMAX(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}

struct Mo {
  using ADD = function<void(int)>;
  using DEL = function<void(int)>;
  using REM = function<void(int)>;

  int width;
  vector<int> left, right, order;
  vector<bool> v;

  Mo(int N, int Q) : width((int)sqrt(N)), order(Q), v(N) {
    iota(begin(order), end(order), 0);
  }

  void add(int l, int r) { /* [l, r) */
    left.emplace_back(l);
    right.emplace_back(r);
  }

  int run(const ADD &add, const DEL &del, const REM &rem) {

    sort(begin(order), end(order), [&](int a, int b) {
      int ablock = left[a] / width, bblock = left[b] / width;
      if (ablock != bblock)
        return ablock < bblock;
      if (ablock & 1)
        return right[a] < right[b];
      return right[a] > right[b];
    });
    int nl = 0, nr = 0;
    auto push = [&](int idx) {
      v[idx].flip();
      if (v[idx])
        add(idx);
      else
        del(idx);
    };
    for (auto idx : order) {
      while (nl > left[idx])
        push(--nl);
      while (nr < right[idx])
        push(nr++);
      while (nl < left[idx])
        push(nl++);
      while (nr > right[idx])
        push(--nr);
      rem(idx);
    }
  }
};

int main() {
  int N, Q;
  cin >> N >> Q;
  vector<int> A(N);
  for (int i = 0; i < N; i++) {
    cin >> A[i];
    --A[i];
  }
  vector<int> f(1000001);
  Mo mo(N, Q);
  for (int i = 0; i < Q; i++) {
    int l, r;
    cin >> l >> r;
    mo.add(--l, r);
  }
  int ret = 0;
  auto add = [&](int idx) {
    if (f[A[idx]]++ == 0)
      ret++;
  };
  auto del = [&](int idx) {
    if (f[A[idx]]-- == 1)
      --ret;
  };
  vector<int> ans(Q);
  auto rem = [&](int idx) { ans[idx] = ret; };
  mo.run(add, del, rem);
  for (int i = 0; i < Q; i++) {
    cout << ans[i] << "\\n";
  }
}