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

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define pb push_back
#define pob pop_back
#define ff first
#define ss second
#define endl "\\n"
#define all(a) a.begin(), a.end()
#define debug(x) cout << x << endl;
#define int long long
#define ordered_set                                                            \\
  tree<int, null_type, less<int>, rb_tree_tag,                                 \\
       tree_order_statistics_node_update>
/* 	1) order_of_key (k) : Number of items strictly smaller than k .
        2) find_by_order(k) : K-th element in a set (counting from zero).
*/
using namespace __gnu_pbds;
using namespace std;
using LD = long double;

const int N = 5e5 + 1;
const int mod = 1e9 + 7;
const int INF = 1e18;
int row[8] = {1, 1, 0, -1, -1, -1, 0, 1};
int col[8] = {0, -1, -1, -1, 0, 1, 1, 1};

int n, q;
vector<int> segT(4 * N);

bool cmp(pair<pair<int, int>, int> &A, pair<pair<int, int>, int> &B) {
  return A.ff.ss < B.ff.ss;
}

void update(int idx, int b, int e, int pos, int val) {
  if (b == e) {
    segT[idx] += val;
    return;
  }
  int mid = b + e >> 1;
  if (pos <= mid)
    update(idx << 1, b, mid, pos, val);
  else
    update(idx << 1 | 1, mid + 1, e, pos, val);
  segT[idx] = segT[idx << 1] + segT[idx << 1 | 1];
}

int query(int idx, int b, int e, int L, int R) {
  if (b > R or e < L)
    return 0;
  if (b >= L and e <= R)
    return segT[idx];
  int mid = b + e >> 1;
  return query(idx << 1, b, mid, L, R) + query(idx << 1 | 1, mid + 1, e, L, R);
}

void solve() {
  cin >> n >> q;
  vector<int> pos(n);

  for (int i = 0; i < n; i++)
    cin >> pos[i];

  vector<pair<pair<int, int>, int>> vp(q);
  vector<int> ans(q);

  map<int, int> prev;

  for (int i = 0; i < q; i++) {
    cin >> vp[i].ff.ff >> vp[i].ff.ss;
    vp[i].ff.ff--;
    vp[i].ff.ss--;
    vp[i].ss = i;
  }

  sort(all(vp), cmp);

  int j = 0;
  for (int i = 0; i < n; i++) {

    if (prev.find(pos[i]) != prev.end()) {
      // cout << prev[pos[i]] << endl;
      update(1, 0, N - 1, prev[pos[i]], -1);
    }

    update(1, 0, N - 1, i, 1);

    while (j < q and vp[j].ff.ss == i) {
      ans[vp[j].ss] = query(1, 0, N - 1, vp[j].ff.ff, vp[j].ff.ss);
      j++;
    }

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

signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);

  int t = 1, i = 1;
  // cin >> t;
  while (t--) {
    // cout << "Case #" << i << ": ";
    solve();
    // i++;
  }
  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define pb push_back
#define pob pop_back
#define ff first
#define ss second
#define endl "\\n"
#define all(a) a.begin(), a.end()
#define debug(x) cout << x << endl;
#define int long long
#define ordered_set                                                            \\
  tree<int, null_type, less<int>, rb_tree_tag,                                 \\
       tree_order_statistics_node_update>
/* 	1) order_of_key (k) : Number of items strictly smaller than k .
        2) find_by_order(k) : K-th element in a set (counting from zero).
*/
using namespace __gnu_pbds;
using namespace std;
using LD = long double;

const int N = 5e5 + 1;
const int mod = 1e9 + 7;
const int INF = 1e18;
int row[8] = {1, 1, 0, -1, -1, -1, 0, 1};
int col[8] = {0, -1, -1, -1, 0, 1, 1, 1};

typedef struct node {
  set<int> SET;
} Node;

int n, q;
vector<int> arr(N);
vector<Node> segT(4 * N);

void build(int idx, int b, int e) {
  if (b == e) {
    segT[idx].SET.insert(arr[b]);
    return;
  }
  int mid = b + e >> 1;
  build(idx << 1, b, mid);
  build(idx << 1 | 1, mid + 1, e);
  segT[idx].SET.insert(all(segT[idx << 1].SET));
  segT[idx].SET.insert(all(segT[idx << 1 | 1].SET));
}

set<int> query(int idx, int b, int e, int L, int R) {
  set<int> ans;
  if (b > R or e < L)
    return ans;
  if (b >= L and e <= R)
    return segT[idx].SET;
  int mid = b + e >> 1;
  set<int> left = query(idx << 1, b, mid, L, R);
  set<int> right = query(idx << 1 | 1, mid + 1, e, L, R);
  ans.insert(all(left));
  ans.insert(all(right));
  return ans;
}

void solve() {
  cin >> n >> q;
  for (int i = 0; i < n; i++)
    cin >> arr[i];
  build(1, 0, n - 1);
  int l, r;
  while (q--) {
    cin >> l >> r;
    l--, r--;
    cout << query(1, 0, n - 1, l, r).size() << endl;
  }
}

signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);

  int t = 1, i = 1;
  // cin >> t;
  while (t--) {
    // cout << "Case #" << i << ": ";
    solve();
    // i++;
  }
  return 0;
}