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

#include <bits/stdc++.h>
using namespace std;
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("-ffloat-store") // to restrict undesirable precision
#pragma GCC optimize(                                                          \\
    "-fno-defer-pop") // to pop argument of function as soon as it returns
#define all(a) a.begin(), a.end()
#define ll long long int
#define ld long double
ll power(ll a, ll b, ll m) {
  if (b == 0)
    return 1;
  if (b == 1)
    return a % m;
  ll t = power(a, b / 2, m) % m;
  t = (t * t) % m;
  if (b & 1)
    t = ((t % m) * (a % m)) % m;
  return t;
}
ll modInverse(ll a, ll m) { return power(a, m - 2, m); }
#define ps push_back
#define fs first
#define sc second
#define takeline cin.ignore();
#define iactive cout.flush();
#define N 500005
#define endl "\\n"
#define mod 1000000007
#define PI 3.141592653589793
//((1.0l)*BIG MULTIPLY MAGIC?)
// string to integer stoi()
// string to long long stoll()
// string.substr(position,length);
// integer to string to_string();
//-----------------------------------------------
ll n, q, ans, cnt[N];
ll block_size, ar[N], answe[N];
pair<pair<ll, ll>, ll> quer[N];
bool mo_cmp(const pair<pair<ll, ll>, ll> &x, const pair<pair<ll, ll>, ll> &y) {
  ll block_x = x.fs.fs / block_size;
  ll block_y = y.fs.fs / block_size;
  if (block_x != block_y) {
    return block_x < block_y;
  }
  return x.fs.sc < y.fs.sc;
}
void mo_add(ll x) {
  if (cnt[x] == 0)
    ans++;
  cnt[x]++;
}
void mo_remove(ll x) {
  cnt[x]--;
  if (cnt[x] == 0)
    ans--;
}
int main() {

  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);

  ll i, j, k, l, n, q;
  cin >> n >> q;
  block_size = sqrt(0.0 + n) + 1;
  for (i = 1; i <= n; i++) {
    cin >> ar[i];
  }
  for (i = 1; i <= q; i++) {
    cin >> quer[i].fs.fs >> quer[i].fs.sc;
    quer[i].sc = i;
  }
  sort(quer + 1, quer + q + 1, mo_cmp);

  ll mo_left = 1, mo_right = 0;
  ans = 0;
  for (i = 1; i <= q; i++) {
    ll left, right;
    left = quer[i].fs.fs;
    right = quer[i].fs.sc;
    // cout<<left<<" "<<right<<endl;
    while (mo_right < right) {
      mo_right++;
      mo_add(ar[mo_right]);
    }
    while (mo_right > right) {
      mo_remove(ar[mo_right]);
      mo_right--;
    }
    while (mo_left < left) {
      mo_remove(ar[mo_left]);
      mo_left++;
    }
    while (mo_left > left) {
      mo_left--;
      mo_add(ar[mo_left]);
    }
    answe[quer[i].sc] = ans;
  }

  for (i = 1; i <= q; i++) {
    cout << answe[i] << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("-ffloat-store") // to restrict undesirable precision
#pragma GCC optimize(                                                          \\
    "-fno-defer-pop") // to pop argument of function as soon as it returns
#define all(a) a.begin(), a.end()
#define ll long long int
#define ld long double
ll power(ll a, ll b, ll m) {
  if (b == 0)
    return 1;
  if (b == 1)
    return a % m;
  ll t = power(a, b / 2, m) % m;
  t = (t * t) % m;
  if (b & 1)
    t = ((t % m) * (a % m)) % m;
  return t;
}
ll modInverse(ll a, ll m) { return power(a, m - 2, m); }
#define ps push_back
#define fs first
#define sc second
#define takeline cin.ignore();
#define iactive cout.flush();
#define N 500005
#define endl "\\n"
#define mod 1000000007
#define PI 3.141592653589793
//((1.0l)*BIG MULTIPLY MAGIC?)
// string to integer stoi()
// string to long long stoll()
// string.substr(position,length);
// integer to string to_string();
//-----------------------------------------------
ll n, ar[N];
set<ll> st[4 * N];
void build(ll node, ll nl, ll nr) {
  if (nl == nr) {
    st[node].insert(ar[nl]);
    return;
  }
  build(2 * node, nl, (nl + nr) / 2);
  build(2 * node + 1, (nl + nr) / 2 + 1, nr);
  st[node].insert(all(st[2 * node]));
  st[node].insert(all(st[2 * node + 1]));
}
set<ll> query(ll node, ll nl, ll nr, ll ql, ll qr) {
  set<ll> l, r, an;
  if (nl > qr || ql > nr) {
    return an;
  }
  if (nl >= ql && qr >= nr) {
    return st[node];
  }

  l = query(2 * node, nl, (nl + nr) / 2, ql, qr);
  r = query(2 * node + 1, (nl + nr) / 2 + 1, nr, ql, qr);
  an.insert(all(l));
  an.insert(all(r));
  return an;
}
int main() {

  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);

  ll i, j, k, l, n, q;
  cin >> n >> q;
  for (i = 1; i <= n; i++) {
    cin >> ar[i];
  }
  build(1, 1, n);
  while (q--) {
    cin >> k >> l;
    set<ll> st = query(1, 1, n, k, l);
    cout << st.size() << endl;
  }
  return 0;
}