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

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define pii pair<int, int>
#define pb push_back
#define fi first
#define se second
#define UP(a, b, c) for (ll(a) = (b); (a) < (c); (a)++)
#define UU(a, b, c) for (ll(a) = (b); (a) <= (c); (a)++)
#define DN(a, b, c) for (ll(a) = (b); (a) > (c); (a)--)
#define DU(a, b, c) for (ll(a) = (b); (a) >= (c); (a)--)

int n, Q, arr[500005];
int fenwick[500005] = {0};
int ans[500005];
int flag[500005];
struct asdf {
  int l, r, idx;
};

asdf q[500005];

void reset() {
  UU(i, 0, 500000) { flag[i] = -1; }
}

bool Compare(asdf a, asdf b) { return a.r < b.r; }

void update(int idx, int v) {
  while (idx <= n) {
    fenwick[idx] += v;
    idx += (idx & (-idx));
  }
}

int query(int idx) {
  int total = 0;
  while (idx > 0) {
    total += fenwick[idx];
    idx -= (idx & (-idx));
  }
  return total;
}

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

  cin >> n >> Q;

  UP(i, 0, n) { cin >> arr[i]; }

  UP(i, 0, Q) {
    cin >> q[i].l >> q[i].r;
    q[i].l--;
    q[i].r--;
    q[i].idx = i;
  }

  reset();

  sort(q, q + Q, Compare);

  int cnt = 0;
  UP(i, 0, n) {
    if (flag[arr[i]] != -1) {
      update(flag[arr[i]] + 1, -1);
    }
    flag[arr[i]] = i;

    update(i + 1, 1);

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

  UP(i, 0, Q) { cout << ans[i] << endl; }

  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define pii pair<int, int>
#define pb push_back
#define fi first
#define se second
#define UP(a, b, c) for (ll(a) = (b); (a) < (c); (a)++)
#define UU(a, b, c) for (ll(a) = (b); (a) <= (c); (a)++)
#define DN(a, b, c) for (ll(a) = (b); (a) > (c); (a)--)
#define DU(a, b, c) for (ll(a) = (b); (a) >= (c); (a)--)

set<int> segment[2000005];
int arr[500005], n, q, diff = 0;
set<int> ans;
bool flag[500005] = {0};
int sz = 0;

void reset() { ans.clear(); }

void build(int i, int l, int r) {
  if (l == r) {
    segment[i].insert(arr[l]);
    return;
  }

  int m = (r + l) / 2;

  build(2 * i, l, m);
  build(1 + 2 * i, m + 1, r);

  segment[i].insert(segment[2 * i].begin(), segment[2 * i].end());

  segment[i].insert(segment[2 * i + 1].begin(), segment[2 * i + 1].end());
}

void query(int idx, int l, int r, int tl, int tr) {
  if (ans.size() == diff || ans.size() == sz) {
    return;
  }
  if (tr < l || tl > r) {
    return;
  }

  if (tl <= l && r <= tr) {
    ans.insert(segment[idx].begin(), segment[idx].end());
    return;
  }

  int m = (r + l) / 2;
  query(2 * idx, l, m, tl, tr);
  query(2 * idx + 1, m + 1, r, tl, tr);
}

void Get(int l, int r) {
  reset();
  query(1, 0, n - 1, l, r);
  printf("%d\\n", ans.size());
}

int main() {
  scanf("%d %d", &n, &q);

  UP(i, 0, n) {
    scanf("%d", &arr[i]);
    if (flag[arr[i]] == 0) {
      flag[arr[i]] = 1;
      diff++;
    }
  }
  build(1, 0, n - 1);

  int l, r;
  UP(i, 0, q) {
    scanf("%d %d", &l, &r);
    sz = r - l + 1;
    Get(l - 1, r - 1);
  }
  return 0;
}