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

#include <bits/stdc++.h>
#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)
using namespace std;
using ll = long long;
template <typename T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
  if (b < a) {
    a = b;
    return 1;
  }
  return 0;
}
template <typename T> vector<T> make_vec(size_t a) { return vector<T>(a); }
template <typename T, typename... Ts> auto make_vec(size_t a, Ts... ts) {
  return vector<decltype(make_vec<T>(ts...))>(a, make_vec<T>(ts...));
}
template <typename T, typename U, typename... V>
typename enable_if<is_same<T, U>::value>::type fill_v(U &u, const V... v) {
  u = U(v...);
}
template <typename T, typename U, typename... V>
typename enable_if<!is_same<T, U>::value>::type fill_v(U &u, const V... v) {
  for (auto &e : u)
    fill_v<T>(e, v...);
}

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

  int n, q;
  cin >> n >> q;
  vector<int> a(n);
  rep(i, n) cin >> a[i], a[i]--;

  vector<int> ql(q), qr(q), qi(q);
  rep(i, q) cin >> ql[i] >> qr[i], ql[i]--;
  iota(qi.begin(), qi.end(), 0);

  int width = sqrt(n);
  sort(qi.begin(), qi.end(), [&](int i, int j) {
    if (ql[i] / width != ql[j] / width)
      return ql[i] < ql[j];
    return qr[i] < qr[j];
  });

  vector<int> cnt(n), ans(q);
  int sum = 0;
  int l = 0, r = 0;

  auto add = [&](int i) {
    if (cnt[a[i]]++ == 0)
      sum++;
  };
  auto del = [&](int i) {
    if (--cnt[a[i]] == 0)
      --sum;
  };

  for (int i : qi) {
    while (ql[i] < l)
      add(--l);
    while (r < qr[i])
      add(r++);
    while (l < ql[i])
      del(l++);
    while (qr[i] < r)
      del(--r);
    ans[i] = sum;
  }

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


Error: TLE

Fixed submission:

#define LOCAL
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define rrep(i, n) for (int i = (n - 1); i >= 0; --i)
#define rep2(i, s, n) for (int i = s; i < (n); ++i)
#define ALL(v) (v).begin(), (v).end()
#define memr(dp, val) memset(dp, val, sizeof(dp))
using namespace std;
typedef long long ll;
static const int INTINF = (INT_MAX >> 1); // 10^9 + 10^7
static const ll LLINF = (LLONG_MAX >> 1);
static const int MAX = 100001;
static const ll MOD = 1000000007;
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> inline bool int_ceil(T a, T b) {
  T res = a / b;
  if (a % b != 0)
    res++;
  return res;
}
template <typename T>
using min_priority_queue = priority_queue<T, vector<T>, greater<T>>;
string to_string(string s) { return '"' + s + '"'; }
string to_string(bool b) { return b ? "true" : "false"; }
template <size_t N> string to_string(bitset<N> bs) {
  string res;
  for (size_t i = 0; i < N; ++i)
    res += '0' + bs[i];
  return res;
}
string to_string(vector<bool> v) {
  string res = "{";
  for (bool e : v)
    res += to_string(e) + ", ";
  return res += "}";
}
template <class T, class U> string to_string(pair<T, U> p);
template <class C> string to_string(C c) {
  string res = "{";
  for (auto e : c)
    res += to_string(e) + ", ";
  return res += "}";
}
template <class T, class U> string to_string(pair<T, U> p) {
  return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}
void debug() { cerr << '\\n'; }
template <class Head, class... Tail> void debug(Head head, Tail... tail) {
  cerr << '\\t' << to_string(head), debug(tail...);
}
#ifdef LOCAL
#define print(...) cerr << "[" << #__VA_ARGS__ << "]:", debug(__VA_ARGS__)
#else
#define print(...)
#endif

class Mo {
public:
  vector<int> left, right, order;
  vector<bool> v;
  int width = 0;
  int nl = 0, nr = 0, ptr = 0;

  Mo(const int n) : width((int)sqrt(n)), v(n) {}

  // [l, r)
  void insert(const int l, const int r) {
    left.push_back(l), right.push_back(r);
  }

  void build() {
    order.resize(left.size());
    iota(order.begin(), order.end(), 0);
    sort(order.begin(), order.end(), [&](const int a, const int b) {
      // 区間が同じでなかったら ... 左端の値でソート
      if (left[a] / width != left[b] / width)
        return left[a] < left[b];
      /// 区間が同じであったら ... 右端の値でソート
      return right[a] < right[b];
    });
  }

  int process() {
    if (ptr == order.size())
      return -1;
    const auto id = order[ptr];
    while (nl > left[id])
      distribute(--nl);
    while (nr < right[id])
      distribute(nr++);
    while (nl < left[id])
      distribute(nl++);
    while (nr > right[id])
      distribute(--nr);
    return (order[ptr++]);
  }

  void distribute(int idx) {
    v[idx].flip();
    if (v[idx])
      add(idx);
    else
      del(idx);
  }

  void add(int idx);

  void del(int idx);
};

int N, A[500100], Q;
int ans[500100];
int cnt[500100], sum;

void Mo::add(int idx) {
  if (cnt[A[idx]]++ == 0)
    ++sum;
}

void Mo::del(int idx) {
  if (--cnt[A[idx]] == 0)
    --sum;
}

int main(int argc, const char *argv[]) {
  std::cout << std::fixed << std::setprecision(15);

  cin >> N >> Q;
  rep(i, N) cin >> A[i];
  Mo mo = Mo(N);
  rep(i, Q) {
    int a, b;
    cin >> a >> b;
    mo.insert(--a, b);
  }
  mo.build();

  rep(i, Q) {
    int id = mo.process();
    if (id == -1)
      break;
    ans[id] = sum;
  }

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

  return 0;
}