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

#include <bits/stdc++.h>

using namespace std;
using int64 = long long;

constexpr int DEBUG = 0;

vector<int64> MoAlgorithm(int n, const vector<tuple<int, int>> &queries,
                          function<void(int)> add_fn,
                          function<void(int)> delete_fn,
                          function<int64(void)> query_fn) {
  vector<tuple<int, int, int>> indexed_queries;
  for (int i = 0; i < queries.size(); i++) {
    const auto [l, r] = queries[i];
    indexed_queries.push_back({i, l, r});
  }

  int bucket_size = sqrt(n);
  sort(indexed_queries.begin(), indexed_queries.end(),
       [&](const auto &t1, const auto &t2) {
         const auto [i1, l1, r1] = t1;
         const auto [i2, l2, r2] = t2;
         int b1 = l1 / bucket_size;
         int b2 = l2 / bucket_size;
         return make_pair(b1, r1) < make_pair(b2, r2);
       });

  vector<int64> answers(queries.size());
  int c_l = 0;
  int c_r = 0;
  for (const auto [i, l, r] : indexed_queries) {
    while (l < c_l) {
      c_l--;
      add_fn(c_l);
    }
    while (c_r < r) {
      add_fn(c_r);
      c_r++;
    }
    while (c_l < l) {
      delete_fn(c_l);
      c_l++;
    }
    while (r < c_r) {
      c_r--;
      delete_fn(c_r);
    }
    answers[i] = query_fn();
  }
  return answers;
}

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

  int n, q;
  cin >> n >> q;

  vector<int> cs(n);
  for (int i = 0; i < n; i++) {
    cin >> cs[i];
    cs[i]--;
  }

  vector<tuple<int, int>> queries;
  for (int i = 0; i < q; i++) {
    int l, r;
    cin >> l >> r;
    l--;
    queries.push_back({l, r});
  }

  vector<int> counts(n);
  int unique_count = 0;
  auto add_fn = [&](int i) {
    if (counts[cs[i]] == 0) {
      unique_count++;
    }
    counts[cs[i]]++;
  };
  auto delete_fn = [&](int i) {
    counts[cs[i]]--;
    if (counts[cs[i]] == 0) {
      unique_count--;
    }
  };
  auto query_fn = [&]() -> int64 { return unique_count; };

  vector<tuple<int, int, int>> indexed_queries;
  for (int i = 0; i < queries.size(); i++) {
    const auto [l, r] = queries[i];
    indexed_queries.push_back({i, l, r});
  }

  int bucket_size = sqrt(n);
  sort(indexed_queries.begin(), indexed_queries.end(),
       [&](const auto &t1, const auto &t2) {
         const auto [i1, l1, r1] = t1;
         const auto [i2, l2, r2] = t2;
         int b1 = l1 / bucket_size;
         int b2 = l2 / bucket_size;
         return make_pair(b1, r1) < make_pair(b2, r2);
       });

  vector<int64> answers(queries.size());
  int c_l = 0;
  int c_r = 0;
  for (const auto [i, l, r] : indexed_queries) {
    while (l < c_l) {
      c_l--;
      add_fn(c_l);
    }
    while (c_r < r) {
      add_fn(c_r);
      c_r++;
    }
    while (c_l < l) {
      delete_fn(c_l);
      c_l++;
    }
    while (r < c_r) {
      c_r--;
      delete_fn(c_r);
    }
    answers[i] = query_fn();
  }

  for (int i = 0; i < q; i++) {
    cout << answers[i] << "\\n";
  }
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;
using int64 = long long;

constexpr int DEBUG = 0;

vector<int64> MoAlgorithm(int n, const vector<tuple<int, int>> &queries,
                          function<void(int)> add_fn,
                          function<void(int)> delete_fn,
                          function<int64(void)> query_fn) {
  vector<tuple<int, int, int>> indexed_queries;
  for (int i = 0; i < queries.size(); i++) {
    const auto [l, r] = queries[i];
    indexed_queries.push_back({i, l, r});
  }

  int bucket_size = sqrt(n);
  sort(indexed_queries.begin(), indexed_queries.end(),
       [&](const auto &t1, const auto &t2) {
         const auto [i1, l1, r1] = t1;
         const auto [i2, l2, r2] = t2;
         int b1 = l1 / bucket_size;
         int b2 = l2 / bucket_size;
         return make_pair(b1, r1) < make_pair(b2, r2);
       });

  vector<int64> answers(queries.size());
  int c_l = 0;
  int c_r = 0;
  for (const auto [i, l, r] : indexed_queries) {
    while (l < c_l) {
      c_l--;
      add_fn(c_l);
    }
    while (c_r < r) {
      add_fn(c_r);
      c_r++;
    }
    while (c_l < l) {
      delete_fn(c_l);
      c_l++;
    }
    while (r < c_r) {
      c_r--;
      delete_fn(c_r);
    }
    answers[i] = query_fn();
  }
  return answers;
}

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

  int n, q;
  cin >> n >> q;

  vector<int> cs(n);
  for (int i = 0; i < n; i++) {
    cin >> cs[i];
    cs[i]--;
  }

  vector<tuple<int, int>> queries;
  for (int i = 0; i < q; i++) {
    int l, r;
    cin >> l >> r;
    l--;
    queries.push_back({l, r});
  }

  vector<int> counts(n);
  int unique_count = 0;
  auto add_fn = [&](int i) {
    if (counts[cs[i]] == 0) {
      unique_count++;
    }
    counts[cs[i]]++;
  };
  auto delete_fn = [&](int i) {
    counts[cs[i]]--;
    if (counts[cs[i]] == 0) {
      unique_count--;
    }
  };
  auto query_fn = [&]() -> int64 { return unique_count; };
  auto ans = MoAlgorithm(n, queries, add_fn, delete_fn, query_fn);
  for (int i = 0; i < q; i++) {
    cout << ans[i] << "\\n";
  }
}