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

#include <bits/stdc++.h>

using namespace std;

const int N = 500010;

struct Mo {
  int sz;
  vector<int> left, right, order;
  vector<bool> check;
  Mo(int n, int q) : sz((int)sqrt(n)), order(q), check(n) {}
  void insert(int l, int r) {
    left.emplace_back(l);
    right.emplace_back(r);
  }
  template <typename ADD, typename DEL, typename REM>
  void build(const ADD &add, const DEL &del, const REM &rem) {
    iota(order.begin(), order.end(), 0);
    sort(order.begin(), order.end(), [&](int a, int b) {
      return (left[a] / sz != left[b] / sz ? left[a] < left[b]
                                           : right[a] < right[b]);
    });
    int l = 0, r = 0;
    auto push = [&](int idx) {
      check[idx].flip();
      if (check[idx])
        add(idx);
      else
        del(idx);
    };
    for (int idx : order) {
      while (l > left[idx])
        push(--l);
      while (r < right[idx])
        push(r++);
      while (l < left[idx])
        push(l++);
      while (r > right[idx])
        push(--r);
      rem(idx);
    }
  }
};

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  int n, m;
  cin >> n >> m;
  vector<int> arr(n);
  for (int i = 0; i < n; ++i)
    cin >> arr[i];
  Mo mo(n, m);
  for (int i = 0; i < m; ++i) {
    int l, r;
    cin >> l >> r;
    mo.insert(l - 1, r);
  }
  vector<int> cnt(n, 0), ans(m);
  int sum = 0;
  auto add = [&](int idx) {
    if (cnt[arr[idx]]++ == 0)
      ++sum;
  };
  auto del = [&](int idx) {
    if (--cnt[arr[idx]] == 0)
      --sum;
  };
  auto rem = [&](int idx) { ans[idx] = sum; };
  mo.build(add, del, rem);
  for (int i = 0; i < m; ++i)
    cout << ans[i] << '\\n';
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

const int N = 500010;

int n, m, bs;
int arr[N], cnt[N], ans[N];
int sum;

struct Mo {
  int sz;
  vector<int> left, right, order;
  vector<bool> check;
  Mo(int n, int q) : sz((int)sqrt(n)), order(q), check(n) {}
  void insert(int l, int r) {
    left.emplace_back(l);
    right.emplace_back(r);
  }
  template <typename ADD, typename DEL, typename REM>
  void build(const ADD &add, const DEL &del, const REM &rem) {
    iota(order.begin(), order.end(), 0);
    sort(order.begin(), order.end(), [&](int a, int b) {
      return (left[a] / sz != left[b] / sz ? left[a] < left[b]
                                           : right[a] < right[b]);
    });
    int l = 0, r = 0;
    auto push = [&](int idx) {
      check[idx].flip();
      if (check[idx])
        add(idx);
      else
        del(idx);
    };
    for (int idx : order) {
      while (l > left[idx])
        push(--l);
      while (r < right[idx])
        push(r++);
      while (l < left[idx])
        push(l++);
      while (r > right[idx])
        push(--r);
      rem(idx);
    }
  }
};

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cin >> n >> m;
  for (int i = 0; i < n; ++i)
    cin >> arr[i];
  Mo mo(n, m);
  for (int i = 0; i < m; ++i) {
    int l, r;
    cin >> l >> r;
    mo.insert(l - 1, r);
  }
  auto add = [&](int idx) {
    if (cnt[arr[idx]]++ == 0)
      ++sum;
  };
  auto del = [&](int idx) {
    if (--cnt[arr[idx]] == 0)
      --sum;
  };
  auto rem = [&](int idx) { ans[idx] = sum; };
  mo.build(add, del, rem);
  for (int i = 0; i < m; ++i)
    cout << ans[i] << '\\n';
}