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

#include <bits/stdc++.h>
#define ll long long
#define ar array
#define AC                                                                     \\
  ios_base::sync_with_stdio(0);                                                \\
  cin.tie(NULL);
using namespace std;
const int M = 1e9 + 7;
const int N = 5 * 1e5;
int n, m;

int arr[N + 5];
int occur[N + 5];
int BIT[N + 5];

struct node {
  int l, r, i;
} q[N];

int block;
int result[N + 5];

bool cmp(node a, node b) { return a.r < b.r; }

int sum(int pos) {
  pos += 1;
  int sum = 0;
  while (pos > 0) {
    sum += BIT[pos];
    pos -= pos & (-pos);
  }
  return sum;
}

void update(int pos, int val) {
  pos += 1;
  while (pos <= n) {
    BIT[pos] += val;
    pos += pos & (-pos);
  }
}

int main() {
  AC cin >> n >> m;
  block = sqrt(n);
  for (int i = 0; i < n; i++) {
    cin >> arr[i];
  }
  for (int i = 0; i < m; i++) {
    int l, r;
    cin >> l >> r;
    q[i].l = --l;
    q[i].r = --r;
    q[i].i = i;
  }

  sort(q, q + m, cmp);
  memset(occur, -1, sizeof(occur));

  int start = 0;
  for (int i = 0; i < m; i++) {
    int L = q[i].l, R = q[i].r;
    // cout<<"current L and R "<<L<<" "<<R<<endl;
    for (int j = start; j <= R; j++) {
      if (occur[arr[j]] >= 0)
        update(occur[arr[j]], -1);
      update(j, 1);
      occur[arr[j]] = j;
    }
    start = R + 1;
    result[q[i].i] = sum(R) - sum(L - 1);
    // cout<<sum(R)<<" "<<sum(L-1)<<endl;
  }

  for (int i = 0; i < m; i++) {
    cout << result[i] << endl;
  }
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define ll long long
#define ar array
#define AC                                                                     \\
  ios_base::sync_with_stdio(0);                                                \\
  cin.tie(NULL);
using namespace std;
const int M = 1e9 + 7;
const int N = 5 * 1e5;
int n, m;
int arr[N + 5];
int occur[N + 5];
struct node {
  int l, r, i;
} q[N];
int block;
int ans = 0;
int result[N + 5];

bool cmp(node a, node b) {
  if (a.l / block != b.l / block)
    return a.l / block < b.l / block;
  return a.r < b.r;
}

void add(int pos) {
  occur[arr[pos]]++;
  if (occur[arr[pos]] == 1)
    ans++;
}

void remove(int pos) {
  occur[arr[pos]]--;
  if (occur[arr[pos]] == 0)
    ans--;
}

int main() {
  AC cin >> n >> m;
  block = sqrt(n);
  for (int i = 0; i < n; i++) {
    cin >> arr[i];
  }
  for (int i = 0; i < m; i++) {
    int l, r;
    cin >> l >> r;
    q[i].l = --l;
    q[i].r = --r;
    q[i].i = i;
  }

  sort(q, q + m, cmp);
  /*
  for(int i=0; i<m; i++){
      cout<<q[i].l<<" "<<q[i].r<<endl;
  }
  cout<<"-------------------"<<endl;
  */

  int cur_l = q[0].l, cur_r = q[0].r;
  for (int i = cur_l; i <= cur_r; i++)
    add(i);
  result[q[0].i] = ans;

  for (int i = 1; i < m; i++) {
    int L = q[i].l, R = q[i].r;
    while (cur_l < L) {
      remove(cur_l);
      cur_l++;
    }
    while (cur_l > L) {
      add(cur_l - 1);
      cur_l--;
    }
    while (cur_r < R) {
      add(cur_r + 1);
      cur_r++;
    }
    while (cur_r > R) {
      remove(cur_r);
      cur_r--;
    }
    result[q[i].i] = ans;
  }
  for (int i = 0; i < m; i++)
    cout << result[i] << endl;
}