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

#include <bits/stdc++.h>
// #include <unordered_map>

using namespace std;
#define inf 1000000000
#define unvisited -1
#define visited 1
#define eps 1e-9
#define mp make_pair
#define pb push_back
#define pi acos(-1.0)
#define uint64 unsigned long long
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> ii;
typedef vector<ii> vii;

const int maxn = 500011;
int a[maxn];
int bit[maxn];
int n;

struct pas {
  int l, r, idx;
};

bool cmp(pas x, pas y) { return x.r < y.r; }

void update(int idx, int val) {
  for (; idx <= n; idx += idx & -idx) {
    bit[idx] += val;
  }
}

int query(int idx) {
  int sum = 0;
  for (; idx > 0; idx -= idx & -idx) {
    sum += bit[idx];
  }
  return sum;
}

void solve(pas queries[], int q) {

  int last_visit[maxn];
  memset(last_visit, -1, sizeof(last_visit));

  int ans[q];
  int cnt = 0;
  for (int i = 0; i < n; i++) {
    if (last_visit[a[i]] != -1) {
      update(last_visit[a[i]] + 1, -1);
    }

    last_visit[a[i]] = i;
    update(i + 1, 1);

    while (cnt < q && queries[cnt].r == i) {
      ans[queries[cnt].idx] = query(queries[cnt].r + 1) - query(queries[cnt].l);
      cnt++;
    }
  }

  for (int i = 0; i < q; i++)
    cout << ans[i] << endl;
}

pas que[maxn];

int main() {
  int q;
  scanf("%d %d", &n, &q);
  int i;
  for (i = 0; i < n; i++) {
    scanf("%d", &a[i]);
  }

  for (i = 0; i < q; i++) {
    scanf("%d %d", &que[i].l, &que[i].r);
    que[i].l--;
    que[i].r--;
    que[i].idx = i;
  }

  sort(que, que + q, cmp);
  solve(que, q);
  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
// #include <unordered_map>

using namespace std;
#define inf 1000000000
#define unvisited -1
#define visited 1
#define eps 1e-9
#define mp make_pair
#define pb push_back
#define pi acos(-1.0)
#define uint64 unsigned long long
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> ii;
typedef vector<ii> vii;

struct query {
  int idx, l, r;
};
const int maxn = 5e5 + 10;
int a[maxn];
int blockSize;
int ans;
int cnt[maxn];
int listans[maxn];
query q[maxn];
unordered_map<int, int> mapper;

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

void add(int indeks) {
  int v = a[indeks];
  int idx = mapper[v];

  cnt[idx]++;
  if (cnt[idx] == 1) {
    ans++;
  }
  // else{
  // 	if((cnt[idx]-1)==v){ans--;}//sebelumnya udah sama..terus ketambahan jadi
  // ga sama..jawaban berkurang
  // }
}

void remove(int indeks) {
  int v = a[indeks];
  int idx = mapper[v];
  cnt[idx]--;
  if (cnt[idx] == 0) {
    ans--;
  }
  // else{
  // 	if((cnt[idx]+1)==v){ans--;}//sebelum dikurangin udah sama kyk v..begitu
  // dikurangin nilai cnt nya..jd ga sama v lagi..nilai ans dikurangin 1
  // }
}

int main() {
  int n, m, i, j;
  scanf("%d %d", &n, &m);
  // printf("n: %d q: %d\\n",n, m);

  blockSize = (int)sqrt(n);
  set<int> s;

  for (i = 0; i < n; i++) {
    scanf("%d", &a[i]);
    s.insert(a[i]);
  }
  int counter = 0;
  for (set<int>::iterator it = s.begin(); it != s.end(); it++) {
    int bil = *it;
    mapper[bil] = counter++;
  }
  // printf("ans\\n");
  for (i = 0; i < m; i++) {
    int kiri, kanan;
    scanf("%d %d", &kiri, &kanan);
    // printf("kiri: %d kanna: %d\\n",kiri, kanan);
    kiri--;
    kanan--;
    q[i].l = kiri;
    q[i].r = kanan;
    q[i].idx = i;
  }
  sort(q, q + m, cmp);
  ans = 0;
  int start = q[0].l, end = start;
  add(start);
  for (i = 0; i < m; i++) {
    int kiri = q[i].l, kanan = q[i].r;
    while (start > kiri) { // ditambahin
      add(--start);
    }
    while (end < kanan) {
      add(++end);
    }
    while (start < kiri) {
      remove(start++);
    }
    while (end > kanan) {
      remove(end--);
    }
    int indeks = q[i].idx;
    listans[indeks] = ans;
  }
  for (i = 0; i < m; i++) {
    printf("%d\\n", listans[i]);
  }

  return 0;
};