Problem p02599 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <bits/stdc++.h>
#define _overload3(_1, _2, _3, name, ...) name
#define _rep(i, n) repi(i, 0, n)
#define repi(i, a, b)                                                          \\
  for (ll i = static_cast<int>(a); i < static_cast<int>(b); ++i)
#define rep(...) _overload3(__VA_ARGS__, repi, _rep, )(__VA_ARGS__) // NOLINT
#define chmax(x, a)                                                            \\
  do {                                                                         \\
    x = max(x, a);                                                             \\
  } while (0)
#define chmin(x, a)                                                            \\
  do {                                                                         \\
    x = min(x, a);                                                             \\
  } while (0)

using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;
typedef pair<ll, ll> PLL;

// Segment Tree {{{
template <typename T> class SegTree {
private:
  int _n;
  T _init_val;
  std::vector<T> _data;
  std::function<T(T, T)> _f;

  T _query(int a, int b, int k, int l, int r) {
    // [a b)と[l r]が交差しない
    if (r <= a || b <= l)
      return _init_val;

    // [a b)が[l r]を含む
    if (a <= l && r <= b)
      return _data[k];

    T vl = _query(a, b, k * 2 + 1, l, (l + r) / 2);
    T vr = _query(a, b, k * 2 + 2, (l + r) / 2, r);

    return _f(vl, vr);
  }

public:
  SegTree(int n, T init_val, std::function<T(T, T)> f) {
    _init_val = init_val;
    _n = 1;
    _f = f;

    while (_n < n)
      _n *= 2;
    _data.resize(2 * _n, init_val);
  }

  T get(int k) { return _data[k + _n - 1]; }

  void update(int k, T a) {
    k += _n - 1;
    _data[k] = a;
    while (k > 0) {
      k = (k - 1) / 2;
      _data[k] = _f(_data[k * 2 + 1], _data[k * 2 + 2]);
    }
  }

  // [a b)の範囲でfを適用
  T query(int a, int b) { return _query(a, b, 0, 0, _n); }

  // 先頭からチェックし，はじめてxを満たしたインデックス
  int lower_bound(T x) { return _lower_bound(x, 0); }

  int _lower_bound(T x, int k) {
    if (k >= _n - 1) {
      return k - (_n - 1); // 葉
    } else if (_data[k] < x) {
      return _n; // 該当なし
    } else if (x <= _data[k * 2 + 1]) {
      return _lower_bound(x, k * 2 + 1);
    } else {
      return _lower_bound(x - _data[k * 2 + 1], k * 2 + 2);
    }
  }
};
// }}}

typedef tuple<ll, ll, ll> T; // {l, r, idx}
ll N, Q;
vector<ll> a;
vector<T> q;
SegTree<ll> st(600000, 0, [](ll a, ll b) { return a + b; });
vector<ll> lastApp(600000, -1);
vector<ll> ans(600000, -1);

int main() {
  cin >> N >> Q;
  a.resize(N);
  q.resize(Q);
  rep(i, N) { cin >> a[i]; }
  rep(i, Q) {
    ll l, r;
    cin >> l >> r;
    l--, r--;
    q[i] = make_tuple(l, r, i);
  }
  sort(begin(q), end(q), [](const auto &x, const auto &y) {
    ll l1 = get<0>(x), r1 = get<1>(x);
    ll l2 = get<0>(y), r2 = get<1>(y);

    if (r1 != r2) {
      return r1 < r2;
    } else {
      return l1 < l2;
    }
  });

  ll i = -1;
  for (auto e : q) {
    ll l = get<0>(e);
    ll r = get<1>(e);
    ll idx = get<2>(e);
    for (ll j = i + 1; j <= r; j++) {
      if (lastApp[a[j]] != -1) {
        st.update(lastApp[a[j]], 0);
      }
      st.update(j, 1);
      lastApp[a[j]] = j;
    }
    i = r;
    ans[idx] = st.query(l, r + 1);
  }
  rep(idx, Q) { cout << ans[idx] << endl; }
  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define _overload3(_1, _2, _3, name, ...) name
#define _rep(i, n) repi(i, 0, n)
#define repi(i, a, b)                                                          \\
  for (ll i = static_cast<int>(a); i < static_cast<int>(b); ++i)
#define rep(...) _overload3(__VA_ARGS__, repi, _rep, )(__VA_ARGS__) // NOLINT
#define chmax(x, a)                                                            \\
  do {                                                                         \\
    x = max(x, a);                                                             \\
  } while (0)
#define chmin(x, a)                                                            \\
  do {                                                                         \\
    x = min(x, a);                                                             \\
  } while (0)

using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;
typedef pair<ll, ll> PLL;

struct Mo {
  using F = function<void(ll)>;

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

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

  // クエリの区間[l r)を登録しておく
  void add(ll l, ll r) {
    left.emplace_back(l);
    right.emplace_back(r);
  }

  // void add (ll idx): idx番目の要素を入れる
  // void del (ll idx): idx番目の要素を削除
  // void rem (ll idx): クエリidx
  void run(const F &add, const F &del, const F &rem) {
    sort(begin(order), end(order), [&](ll a, ll b) {
      ll 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];
    });
    ll nl = 0, nr = 0;
    auto push = [&](ll 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);
    }
  }
};

ll N, Q;
vector<ll> f(600000);

int main() {
  cin >> N >> Q;
  vector<ll> A(N);
  rep(i, N) { cin >> A[i]; }
  Mo mo(N, Q);
  rep(i, Q) {
    ll l, r;
    cin >> l >> r;
    mo.add(l - 1, r);
  }

  ll ret = 0;
  vector<ll> ans(Q);
  auto add = [&](ll idx) {
    if (f[A[idx]]++ == 0)
      ret++;
  };
  auto del = [&](ll idx) {
    if (f[A[idx]]-- == 1)
      --ret;
  };
  auto rem = [&](ll idx) { ans[idx] = ret; };
  mo.run(add, del, rem);
  rep(i, Q) { cout << ans[i] << endl; }
  return 0;
}