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

#pragma GCC optimize("O2")
// luogu-judger-enable-o2
#include <bits/stdc++.h>
using namespace std;
const int maxn = 500010;
const int maxm = 500010;
typedef long long ll;
template <class T> inline void read(T &a) {
  T s = 0, w = 1;
  char c = getchar();
  while (c < '0' || c > '9') {
    if (c == '-')
      w = -1;
    c = getchar();
  }
  while (c >= '0' && c <= '9') {
    s = (s << 1) + (s << 3) + (c ^ 48);
    c = getchar();
  }
  a = s * w;
}
int n, m, Block_Size;
int Block[maxn];
struct Que {
  int l, r, Id;
};
inline int cmp(const Que &a, const Que &b) {
  return (Block[a.l] < Block[b.l]) || (Block[a.l] == Block[b.l] && a.r < b.r);
}
Que q[maxm];
int Answer[maxm];
int col[maxn];
int sum[maxn], Sum;
inline void Update(int a, int otp) {
  if (otp == 1 && sum[col[a]] == 0)
    Sum++;
  if (otp == -1 && sum[col[a]] == 1)
    Sum--;
  sum[col[a]] += otp;
}
int main() {

  read(n);
  read(m);
  Block_Size = (int)sqrt(n);
  for (int i = 1; i <= n; i++) {
    read(col[i]);
    Block[i] = i / Block_Size + 1;
  }
  for (int i = 1; i <= m; i++) {
    read(q[i].l), read(q[i].r);
    q[i].Id = i;
  }
  sort(q + 1, q + 1 + m, cmp);
  int l(1), r(0);
  for (int i = 1; i <= m; i++) {
    while (l < q[i].l)
      Update(l++, -1);
    while (l > q[i].l)
      Update(--l, 1);
    while (r < q[i].r)
      Update(++r, 1);
    while (r > q[i].r)
      Update(r--, -1);
    Answer[q[i].Id] = Sum;
  }
  for (int i = 1; i <= m; i++) {
    printf("%d\\n", Answer[i]);
  }
  return 0;
}


Error: TLE

Fixed submission:

// luogu-judger-enable-o2
#include <bits/stdc++.h>
using namespace std;
const int maxn = 500010;
const int maxm = 500010;
typedef long long ll;
template <class T> inline void read(T &a) {
  T s = 0, w = 1;
  char c = getchar();
  while (c < '0' || c > '9') {
    if (c == '-')
      w = -1;
    c = getchar();
  }
  while (c >= '0' && c <= '9') {
    s = (s << 1) + (s << 3) + (c ^ 48);
    c = getchar();
  }
  a = s * w;
}
int n, m, Block_Size;
int Block[maxn];
struct Que {
  int l, r, Id;
};
inline int cmp(const Que &a, const Que &b) {
  return (Block[a.l] < Block[b.l]) || (Block[a.l] == Block[b.l] && a.r < b.r);
}
struct Ans {
  int a, b;
  int Id;
};
ll Gcd(ll a, ll b) {
  if (b == 0)
    return a;
  else
    return Gcd(b, a % b);
}
Que q[maxm];
Ans Answer[maxm];
int col[maxn];
long long sum[maxn], Sum;
void Update(int a, int otp) {
  if (otp == 1 && sum[col[a]] == 0)
    Sum++;
  if (otp == -1 && sum[col[a]] == 1)
    Sum--;
  sum[col[a]] += otp;
}
int main() {

  read(n);
  read(m);
  Block_Size = (int)sqrt(n);
  for (int i = 1; i <= n; i++) {
    read(col[i]);
    Block[i] = i / Block_Size + 1;
  }
  for (int i = 1; i <= m; i++) {
    read(q[i].l), read(q[i].r);
    q[i].Id = i;
  }
  sort(q + 1, q + 1 + m, cmp);
  int l(1), r(0);
  for (int i = 1; i <= m; i++) {
    while (l < q[i].l) {
      Update(l++, -1);
    }
    while (l > q[i].l) {
      Update(--l, 1);
    }
    while (r < q[i].r) {
      Update(++r, 1);
    }
    while (r > q[i].r) {
      Update(r--, -1);
    }
    Answer[q[i].Id].a = Sum;
  }
  for (int i = 1; i <= m; i++) {
    printf("%d\\n", Answer[i].a);
  }
  return 0;
}