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

#include <algorithm>
#include <cctype>
#include <climits>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;

using ii = pair<int, int>;
using vi = vector<int>;
using vii = vector<ii>;
using vvi = vector<vi>;

using ll = long long int;

#define mp(a, b) make_pair(a, b)

#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

const int MOD = 1000 * 1000 * 1000 + 7;

int N;
int sqrtN;

struct query {
  int l, r, idx, res;
};

int v[500000];
query queries[500000];

struct cmp {
  bool operator()(query const &q1, query const &q2) {
    if (q1.l / sqrtN != q2.l / sqrtN) {
      return q1.l / sqrtN < q2.l / sqrtN;
    }
    return q1.r < q2.r;
  }
};

struct cmp2 {
  bool operator()(query const &q1, query const &q2) { return q1.idx < q2.idx; }
};

int main() {
  cin.tie(NULL);
  ios_base::sync_with_stdio(false);

  int n, q;
  cin >> n >> q;

  for (int i = 0; i < n; ++i)
    cin >> v[i];
  for (int i = 0; i < q; ++i) {
    cin >> queries[i].l >> queries[i].r;
    --queries[i].l;
    --queries[i].r;
    queries[i].idx = i;
  }

  N = n;
  sqrtN = sqrt(n);

  sort(queries, queries + q, cmp());

  int currL = 0, currR = 0;

  vi colores(500001);
  int dif = 0;

  for (int i = 0; i < q; i++) {
    while (currR <= queries[i].r) {
      if (colores[v[currR]] == 0) {
        ++dif;
      }
      ++colores[v[currR]];

      currR++;
    }
    while (currR > queries[i].r + 1) { // Remove elements of previous range.
      if (colores[v[currR - 1]] == 1) {
        --dif;
      }
      --colores[v[currR - 1]];

      currR--; // sum of [L, R] is in currSum
    }
    while (currL < queries[i].l) { // Remove extra elements of previous range.
      if (colores[v[currL]] == 1) {
        --dif;
      }
      --colores[v[currL]];

      currL++;
    }
    while (currL > queries[i].l) { // Add Elements of currentRange
      if (colores[v[currL - 1]] == 0) {
        ++dif;
      }
      ++colores[v[currL - 1]];

      currL--;
    }

    queries[i].res = dif;
  }

  sort(queries, queries + q, cmp2());

  for (int i = 0; i < q; ++i)
    cout << queries[i].res << '\\n';

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cctype>
#include <climits>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;

using ii = pair<int, int>;
using vi = vector<int>;
using vii = vector<ii>;
using vvi = vector<vi>;

using ll = long long int;

#define mp(a, b) make_pair(a, b)

#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

const int MOD = 1000 * 1000 * 1000 + 7;

int N;
int sqrtN;

struct query {
  int l, r, idx, res;
};

int v[500000];
query queries[500000];

struct cmp {
  bool operator()(query const &q1, query const &q2) {
    if (q1.l / sqrtN != q2.l / sqrtN) {
      return q1.l / sqrtN < q2.l / sqrtN;
    }
    return q1.r < q2.r;
  }
};

struct cmp2 {
  bool operator()(query const &q1, query const &q2) { return q1.idx < q2.idx; }
};

int main() {
  cin.tie(NULL);
  ios_base::sync_with_stdio(false);

  int n, q;
  cin >> n >> q;

  for (int i = 0; i < n; ++i)
    cin >> v[i];
  for (int i = 0; i < q; ++i) {
    cin >> queries[i].l >> queries[i].r;
    --queries[i].l;
    --queries[i].r;
    queries[i].idx = i;
  }

  N = n;
  sqrtN = sqrt(n);

  sort(queries, queries + q, cmp());

  int currL = 0, currR = 0;

  map<int, int> colores;

  for (int i = 0; i < q; i++) {
    while (currR <= queries[i].r) {
      if (colores.find(v[currR]) == colores.end()) {
        colores.insert(mp(v[currR], 1));
      } else {
        ++colores[v[currR]];
      }
      currR++;
    }
    while (currR > queries[i].r + 1) { // Remove elements of previous range.
      if (colores[v[currR - 1]] == 1) {
        colores.erase(v[currR - 1]);
      } else {
        --colores[v[currR - 1]];
      }
      currR--; // sum of [L, R] is in currSum
    }
    while (currL < queries[i].l) { // Remove extra elements of previous range.
      if (colores[v[currL]] == 1) {
        colores.erase(v[currL]);
      } else {
        --colores[v[currL]];
      }
      currL++;
    }
    while (currL > queries[i].l) { // Add Elements of currentRange
      if (colores.find(v[currL - 1]) == colores.end()) {
        colores.insert(mp(v[currL - 1], 1));
      } else {
        ++colores[v[currL - 1]];
      }
      currL--;
    }

    queries[i].res = colores.size();
  }

  sort(queries, queries + q, cmp2());

  for (int i = 0; i < q; ++i)
    cout << queries[i].res << '\\n';

  return 0;
}