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

#pragma GCC target("avx2")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("O3")
#include "bits/stdc++.h"
#include <random>
#include <unordered_map>
#include <unordered_set>
using namespace std;
typedef long long ll;
const ll MOD = 1'000'000'007LL; /*998'244'353LL;*/
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for (int(i) = 0; (i) < (n); (i)++)
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};

int N, Q;
int C[500000];
vector<pair<int, pair<int, int>>> query[800];
int ans[500000] = {};

signed main() {
  cin >> N >> Q;
  rep(i, N) {
    cin >> C[i];
    C[i]--;
  }
  rep(i, Q) {
    int l, r;
    cin >> l >> r;
    query[(l - 1) / 800].pb({r, {l - 1, i}});
  }

  rep(i, 800) {
    vector<int> cnt(N, 0);
    int tmp = 0;
    int L = 800 * i;
    int R = 800 * i;
    sort(all(query[i]));
    rep(j, query[i].size()) {
      int l = query[i][j].second.first;
      int r = query[i][j].first;
      int a = query[i][j].second.second;
      while (R < r) {
        cnt[C[R]]++;
        if (cnt[C[R]] == 1)
          tmp++;
        R++;
      }
      while (L < l) {
        cnt[C[L]]--;
        if (cnt[C[L]] == 0)
          tmp--;
        L++;
      }
      while (L > l) {
        cnt[C[L - 1]]++;
        if (cnt[C[L - 1]] == 1)
          tmp++;
        L--;
      }
      ans[a] = tmp;
    }
  }

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

Error: TLE

Fixed submission:

#pragma GCC target("avx2")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("O3")
#include "bits/stdc++.h"
#include <random>
#include <unordered_map>
#include <unordered_set>
using namespace std;
typedef long long ll;
const ll MOD = 1'000'000'007LL; /*998'244'353LL;*/
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for (int(i) = 0; (i) < (n); (i)++)
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};

template <typename T> struct SegmentTree {
private:
  int N;
  vector<T> node;
  function<T(T, T)> F;
  T E;

public:
  void init(int n, function<T(T, T)> f, T e, vector<T> def) {
    F = f;
    E = e;
    N = 1;
    while (N < n)
      N = (N << 1);
    node.assign(2 * N - 1, e);
    for (int i = 0; i < n; i++)
      node[N - 1 + i] = def[i];
    for (int i = N - 2; i >= 0; i--)
      node[i] = F(node[(i << 1) + 1], node[(i << 1) + 2]);
  }
  T &operator[](int a) { return node[N - 1 + a]; }
  void update(int a, T x) {
    a += N - 1;
    node[a] = x;
    while (a > 0) {
      a = (a - 1) >> 1;
      node[a] = F(node[(a << 1) + 1], node[(a << 1) + 2]);
    }
  }
  T query(int a, int b, int k = 0, int l = 0, int r = -1) {
    if (r == -1)
      r = N;
    if (b <= l || r <= a)
      return E;
    if (a <= l && r <= b)
      return node[k];
    return F(query(a, b, (k << 1) + 1, l, (l + r) >> 1),
             query(a, b, (k << 1) + 2, (l + r) >> 1, r));
  }
};

int N, Q;
vector<deque<int>> c;
SegmentTree<deque<int>> st;

signed main() {
  cin >> N >> Q;
  c.resize(N);
  rep(i, N) {
    int a;
    cin >> a;
    c[i].pb(a);
  }
  st.init(
      N,
      [](deque<int> a, deque<int> b) {
        deque<int> ret;
        while (a.size() > 0 || b.size() > 0) {
          if (a.size() > 0 && b.size() > 0 && a[0] == b[0]) {
            b.pop_front();
            continue;
          }
          if (a.size() == 0) {
            ret.push_back(b[0]);
            b.pop_front();
            continue;
          }
          if (b.size() == 0) {
            ret.push_back(a[0]);
            a.pop_front();
            continue;
          }
          if (a[0] < b[0]) {
            ret.push_back(a[0]);
            a.pop_front();
            continue;
          } else {
            ret.push_back(b[0]);
            b.pop_front();
            continue;
          }
        }
        return ret;
      },
      {}, c);

  rep(i, Q) {
    int l, r;
    cin >> l >> r;
    cout << st.query(l - 1, r).size() << endl;
  }
}