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

#include <bits/stdc++.h>

using namespace std;

#define fi first
#define se second
#define eb emplace_back
#define mt make_tuple
#define all(x) (x).begin(), (x).end()
#define sz(x) int(x.size())
#define MOD 1000000007

typedef long long ll;
typedef pair<int, int> ii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef long double ld;

const ll INF = 63;
const int mxn = 5e5 + 5;
bool DEBUG = 0;

struct BIT {
  vi bit;
  int N;
  void init(int n) {
    N = n;
    bit.assign(n + 1, 0);
  }
  void add(int pos, int val) {
    while (pos <= N) {
      bit[pos] += val;
      pos += pos & -pos;
    }
  }
  int query(int pos) {
    int res = 0;
    while (pos) {
      res += bit[pos];
      pos -= pos & -pos;
    }
    return res;
  }
  int sum(int le, int ri) {
    if (le != 1)
      return query(ri) - query(le - 1);
    else
      return query(ri);
  }
} bit;

vector<ii> qry[mxn];
int ans[mxn];

int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  // freopen("input.txt","r",stdin); freopen("output.txt","w",stdout);
  int n, q;
  cin >> n >> q;
  bit.init(n);
  vi prev;
  prev.resize(n + 1);
  int c[n];
  for (int i = 1; i <= n; i++) {
    cin >> c[i];
  }
  for (int i = 0; i < q; i++) {
    int le, ri;
    cin >> le >> ri;
    qry[ri].eb(le, i);
  }
  for (int i = 1; i <= n; i++) {
    if (prev[c[i]])
      bit.add(prev[c[i]], -1);
    bit.add(i, 1);
    prev[c[i]] = i;
    for (ii x : qry[i]) {
      ans[x.se] = bit.sum(x.fi, i);
    }
  }
  for (int i = 0; i < q; i++) {
    cout << ans[i] << "\\n";
  }
}

// READ & UNDERSTAND
// ll, int overflow, array bounds, memset(0)
// special cases (n=1?), n+1 (1-index)
// do smth instead of nothing & stay organized
// WRITE STUFF DOWN


Error: TLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

#define fi first
#define se second
#define eb emplace_back
#define mt make_tuple
#define all(x) (x).begin(), (x).end()
#define sz(x) int(x.size())
#define MOD 1000000007

typedef long long ll;
typedef pair<int, int> ii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef long double ld;

const ll INF = LLONG_MAX;
const int mxn = 5e5 + 5;
bool DEBUG = 0;

unordered_set<int> tree[mxn * 4];
int c[mxn], n;

unordered_set<int> pushup(unordered_set<int> le, unordered_set<int> ri) {
  if (sz(le) < sz(ri))
    swap(le, ri);
  for (int x : ri)
    le.insert(x);
  return le;
}

void build(int id = 1, int le = 0, int ri = n - 1) {
  if (le == ri) {
    tree[id].insert(c[le]);
  } else {
    int mid = (le + ri) / 2;
    build(id * 2, le, mid);
    build(id * 2 + 1, mid + 1, ri);
    tree[id] = pushup(tree[id * 2], tree[id * 2 + 1]);
  }
}

unordered_set<int> query(int x, int y, int id = 1, int le = 0, int ri = n - 1) {
  if (x > ri || le > y) {
    unordered_set<int> rt;
    return rt;
  }
  if (x <= le && ri <= y)
    return tree[id];
  int mid = (le + ri) / 2;
  unordered_set<int> left = query(x, y, id * 2, le, mid);
  unordered_set<int> right = query(x, y, id * 2 + 1, mid + 1, ri);
  return pushup(left, right);
}

int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  // freopen("input.txt","r",stdin); freopen("output.txt","w",stdout);
  cin >> n;
  int q;
  cin >> q;
  for (int i = 0; i < n; i++)
    cin >> c[i];
  build();
  while (q--) {
    int u, v;
    cin >> u >> v;
    u--;
    v--;
    cout << sz(query(u, v)) << '\\n';
  }
}

// READ & UNDERSTAND
// ll, int overflow, array bounds, memset(0)
// special cases (n=1?), n+1 (1-index)
// do smth instead of nothing & stay organized
// WRITE STUFF DOWN