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

#include <bits/stdc++.h>
#define pb push_back
#define SZ(x) ((int)(x.size()))
#define FOR(i, s, n) for (ll i = (s); (i) < (n); ++i)
#define FORD(i, s, l) for (ll i = (s); (i) >= l; --i)
#define F first
#define S second
#define TC                                                                     \\
  int __tc;                                                                    \\
  cin >> __tc;                                                                 \\
  FOR(case_num, 1, __tc + 1)
#define TEST(x, i) ((x) & (1ll << (i)))
#define SET(x, i) ((x) | (1ll << (i)))
#define FLIP(x, i) ((x) ^ (1ll << (i)))
#define CLEAR(x, i) ((x) & ~(1ll << (i)))

const double pi = 4 * atan(1);
using namespace std;
typedef long long ll;

const ll MOD = 1000000007;
const int MAXN = 500005;

int cnt[MAXN];
int num[MAXN];
int distinct;
int answers[MAXN];

// Mo's algorithm from cp-algorithms.com

void remove(int idx) {
  if (cnt[num[idx]] == 1) {
    distinct--;
  }
  cnt[num[idx]]--;
}
void add(int idx) {
  if (!cnt[num[idx]]) {
    distinct++;
  }
  cnt[num[idx]]++;
}
int get_answer() { return distinct; }

const int block_size = 708;

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

void mo_s_algorithm(vector<Query> &queries) {
  sort(queries.begin(), queries.end());

  int cur_l = 0;
  int cur_r = -1;
  for (Query q : queries) {
    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();
  }
}

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

  int n, q;
  cin >> n >> q;
  FOR(i, 0, n) { cin >> num[i]; }
  vector<Query> queries;
  FOR(i, 0, q) {
    Query qq;
    cin >> qq.l >> qq.r;
    qq.l--;
    qq.r--;
    qq.idx = i;
    queries.pb(qq);
  }
  mo_s_algorithm(queries);
  FOR(i, 0, q) { cout << answers[i] << "\\n"; }
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define pb push_back
#define SZ(x) ((int)(x.size()))
#define FOR(i, s, n) for (ll i = (s); (i) < (n); ++i)
#define FORD(i, s, l) for (ll i = (s); (i) >= l; --i)
#define F first
#define S second
#define TC                                                                     \\
  int __tc;                                                                    \\
  cin >> __tc;                                                                 \\
  FOR(case_num, 1, __tc + 1)
#define TEST(x, i) ((x) & (1ll << (i)))
#define SET(x, i) ((x) | (1ll << (i)))
#define FLIP(x, i) ((x) ^ (1ll << (i)))
#define CLEAR(x, i) ((x) & ~(1ll << (i)))

const double pi = 4 * atan(1);
using namespace std;
typedef long long ll;

const ll MOD = 1000000007;
const int MAXN = 500005;

int cnt[MAXN];
int num[MAXN];
int distinct;
int answers[MAXN];

int logn = 19;
int maxn = 1 << logn;

// https://codeforces.com/blog/entry/61203
long long hilbertorder(int x, int y) {
  long long d = 0;
  for (int s = 1 << (logn - 1); s; s >>= 1) {
    bool rx = x & s, ry = y & s;
    d = d << 2 | rx * 3 ^ static_cast<int>(ry);
    if (!ry) {
      if (rx) {
        x = maxn - x;
        y = maxn - y;
      }
      swap(x, y);
    }
  }
  return d;
}

// Mo's algorithm from cp-algorithms.com

void remove(int idx) {
  if (cnt[num[idx]] == 1) {
    distinct--;
  }
  cnt[num[idx]]--;
}
void add(int idx) {
  if (!cnt[num[idx]]) {
    distinct++;
  }
  cnt[num[idx]]++;
}
int get_answer() { return distinct; }

struct Query {
  int l, r, idx;
  int ord;
  bool operator<(Query other) const { return ord < other.ord; }
};

void mo_s_algorithm(vector<Query> &queries) {
  sort(queries.begin(), queries.end());

  int cur_l = 0;
  int cur_r = -1;
  for (Query q : queries) {
    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();
  }
}

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

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

  logn = (int)ceil(log2(n));
  maxn = 1 << logn;

  FOR(i, 0, n) { cin >> num[i]; }
  vector<Query> queries;
  FOR(i, 0, q) {
    Query qq;
    cin >> qq.l >> qq.r;
    qq.l--;
    qq.r--;
    qq.ord = hilbertorder(qq.l, qq.r);
    qq.idx = i;
    queries.pb(qq);
  }
  mo_s_algorithm(queries);
  FOR(i, 0, q) { cout << answers[i] << "\\n"; }
}