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

#include <bits/stdc++.h>

using namespace std;

const int MAX = 5 * 100001;

int ans = 0;
vector<int> cnt(MAX);
vector<int> a(MAX);
void remove(int idx) {
  --cnt[a[idx]];
  if (cnt[a[idx]] == 0)
    --ans;
}
void add(int idx) {
  ++cnt[a[idx]];
  if (cnt[a[idx]] == 1)
    ++ans;
}
int get_answer() { return ans; }

int block_size = 600;

struct Query {
  int l, r, idx;
  Query(int l, int r, int idx) {
    this->l = l;
    this->r = r;
    this->idx = idx;
  }
  bool operator<(Query other) const {
    return make_pair(l, r) < make_pair(other.l, other.r);
  }
};

bool cmp(const Query &p, const Query &q) {
  if (p.l / block_size != q.l / block_size)
    return p < q;
  return (p.l / block_size & 1) ? (p.r < q.r) : (p.r > q.r);
}

vector<int> mo_s_algorithm(vector<Query> queries) {
  vector<int> answers(queries.size());
  sort(queries.begin(), queries.end(), cmp);

  // TODO: initialize data structure

  int cur_l = 0;
  int cur_r = -1;
  // invariant: data structure will always reflect the range [cur_l, cur_r]
  for (Query q : queries) {
    //	cout << q.l << "  --  " << q.r << "\\n";
    while (cur_l > q.l) {
      cur_l--;
      add(cur_l);
    }
    while (cur_r < q.r) {
      cur_r++;
      add(cur_r);
    }
    while (cur_l < q.l) {
      remove(cur_l);
      cur_l++;
    }
    while (cur_r > q.r) {
      remove(cur_r);
      cur_r--;
    }
    answers[q.idx] = get_answer();
  }
  return answers;
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL), cout.tie(NULL);
  int n, q;
  cin >> n >> q;
  for (int i = 0; i < n; i++) {
    cin >> a[i];
  }
  vector<Query> qu;
  for (int i = 0; i < q; i++) {
    int l, r;
    cin >> l >> r;
    --l, --r;
    Query tmp(l, r, i);
    //	cout << tmp.l << " " << tmp.r << "\\n";
    qu.push_back(tmp);
  }
  vector<int> ans = mo_s_algorithm(qu);
  for (int i = 0; i < q; i++) {
    cout << ans[i] << " \\n";
  }
  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

const int MAX = 5 * 100001;

int ans = 0;
vector<int> cnt(MAX);
vector<int> a(MAX);
void remove(int idx) {
  --cnt[a[idx]];
  if (cnt[a[idx]] == 0)
    --ans;
}
void add(int idx) {
  ++cnt[a[idx]];
  if (cnt[a[idx]] == 1)
    ++ans;
}
int get_answer() { return ans; }

int block_size = 600;

struct Query {
  int l, r, idx;
  Query(int l, int r, int idx) {
    this->l = l;
    this->r = r;
    this->idx = idx;
  }
  bool operator<(Query other) const {
    return make_pair(l / block_size, r) <
           make_pair(other.l / block_size, other.r);
  }
};

vector<int> mo_s_algorithm(vector<Query> queries) {
  vector<int> answers(queries.size());
  sort(queries.begin(), queries.end());

  // TODO: initialize data structure

  int cur_l = 0;
  int cur_r = -1;
  // invariant: data structure will always reflect the range [cur_l, cur_r]
  for (Query q : queries) {
    //	cout << q.l << "  --  " << q.r << "\\n";
    while (cur_l > q.l) {
      cur_l--;
      add(cur_l);
    }
    while (cur_r < q.r) {
      cur_r++;
      add(cur_r);
    }
    while (cur_l < q.l) {
      remove(cur_l);
      cur_l++;
    }
    while (cur_r > q.r) {
      remove(cur_r);
      cur_r--;
    }
    answers[q.idx] = get_answer();
  }
  return answers;
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL), cout.tie(NULL);
  int n, q;
  cin >> n >> q;
  for (int i = 0; i < n; i++) {
    cin >> a[i];
  }
  vector<Query> qu;
  for (int i = 0; i < q; i++) {
    int l, r;
    cin >> l >> r;
    --l, --r;
    Query tmp(l, r, i);
    //	cout << tmp.l << " " << tmp.r << "\\n";
    qu.push_back(tmp);
  }
  vector<int> ans = mo_s_algorithm(qu);
  for (int i = 0; i < q; i++) {
    cout << ans[i] << " \\n";
  }
  return 0;
}