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

#include <bits/stdc++.h>
using namespace std;

#define N 500001
#define A 500001
#define BLOCK 710 // ~sqrt(N)

int cnt[A], a[N], ans[N], answer = 0;
long long arr[N];
struct node {
  int L, R, i;
} q[N];

bool cmp(node x, node y) {
  if (x.L / BLOCK != y.L / BLOCK) {
    // different blocks, so sort by block.
    return x.L / BLOCK < y.L / BLOCK;
  }
  // same block, so sort by R value
  return x.R < y.R;
}

void add(int position) {
  cnt[a[position]]++;
  if (cnt[a[position]] == 1) {
    answer++;
  }
}

void remove(int position) {
  cnt[a[position]]--;
  if (cnt[a[position]] == 0) {
    answer--;
  }
}

unordered_map<long long, int> coords;

int main() {
  int n;
  int m;
  scanf("%d %d", &n, &m);
  coords.clear();
  int t = 0;
  for (int i = 0; i < n; i++)
    scanf("%lld", &arr[i]);
  for (int i = 0; i < n; i++) {
    if (coords.find(arr[i]) == coords.end())
      coords[arr[i]] = t++;
  }
  for (int i = 0; i < n; i++)
    a[i] = coords[arr[i]];
  for (int i = 0; i < m; i++) {
    scanf("%d%d", &q[i].L, &q[i].R);
    q[i].L--;
    q[i].R--;
    q[i].i = i;
  }

  sort(q, q + m, cmp);

  int currentL = 0, currentR = 0;
  for (int i = 0; i < m; i++) {
    int L = q[i].L, R = q[i].R;
    while (currentL < L) {
      remove(currentL);
      currentL++;
    }
    while (currentL > L) {
      add(currentL - 1);
      currentL--;
    }
    while (currentR <= R) {
      add(currentR);
      currentR++;
    }
    while (currentR > R + 1) {
      remove(currentR - 1);
      currentR--;
    }
    ans[q[i].i] = answer;
  }

  for (int i = 0; i < m; i++)
    printf("%d\\n", ans[i]);
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

#define N 500001
#define A 500001
#define BLOCK 710 // ~sqrt(N)

int cnt[A], a[N], ans[N], answer = 0;
long long arr[N];
struct node {
  int L, R, i;
} q[N];

bool cmp(node x, node y) {
  if (x.L / BLOCK != y.L / BLOCK) {
    // different blocks, so sort by block.
    return x.L / BLOCK < y.L / BLOCK;
  }
  // same block, so sort by R value
  return x.R < y.R;
}

void add(int position) {
  cnt[a[position]]++;
  if (cnt[a[position]] == 1) {
    answer++;
  }
}

void remove(int position) {
  cnt[a[position]]--;
  if (cnt[a[position]] == 0) {
    answer--;
  }
}

map<long long, int> coords;

int main() {
  int n;
  scanf("%d", &n);
  int m;
  coords.clear();
  int t = 0;
  scanf("%d", &m);
  for (int i = 0; i < n; i++)
    scanf("%lld", &arr[i]);
  for (int i = 0; i < n; i++) {
    if (coords.find(arr[i]) == coords.end())
      coords[arr[i]] = t++;
  }
  for (int i = 0; i < n; i++)
    a[i] = coords[arr[i]];
  for (int i = 0; i < m; i++) {
    scanf("%d%d", &q[i].L, &q[i].R);
    q[i].L--;
    q[i].R--;
    q[i].i = i;
  }

  sort(q, q + m, cmp);

  int currentL = 0, currentR = 0;
  for (int i = 0; i < m; i++) {
    int L = q[i].L, R = q[i].R;
    while (currentL < L) {
      remove(currentL);
      currentL++;
    }
    while (currentL > L) {
      add(currentL - 1);
      currentL--;
    }
    while (currentR <= R) {
      add(currentR);
      currentR++;
    }
    while (currentR > R + 1) {
      remove(currentR - 1);
      currentR--;
    }
    ans[q[i].i] = answer;
  }

  for (int i = 0; i < m; i++)
    printf("%d\\n", ans[i]);
}