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

#include <bits/stdc++.h>

#define ull unsigned long long
#define ll long long
#define pb push_back
#define pii pair<int, int>
#define FAST                                                                   \\
  ios_base::sync_with_stdio(0);                                                \\
  cin.tie(0);                                                                  \\
  cout.tie(0);
#define MAXN 500100

using namespace std;

const int INF = 1e9 + 7;

struct item {
  ll sum;
};

struct SegTree {
  int sz, n;
  vector<item> values;

  //-----<Set up the neutral element, single, and merge for current item>-----//
  item NEUTRAL_ELEMENT = {0};

  item merge(item a, item b) { return {a.sum + b.sum}; }

  item single(int v) { return {v}; }
  //-----</Set up the neutral element, single, and merge for current
  //item>-----//

  void init(int n) {
    sz = 1;
    while (sz < n)
      sz *= 2;
    values.assign(sz * 2, NEUTRAL_ELEMENT);
    return;
  }

  void set(int i, int v, int x, int lx, int rx) {

    if (rx - lx == 1) {
      values[x] = single(v); // base case, set bottom level
      return;
    }

    int m = lx + (rx - lx) / 2;

    if (m > i)
      set(i, v, 2 * x + 1, lx, m); // go left
    else
      set(i, v, 2 * x + 2, m, rx); // go right

    //-----<Do associative operation>-----//
    values[x] = merge(values[x * 2 + 1], values[x * 2 + 2]);
    //-----</Do associative operation>-----//
  }

  void set(int i, int v) {
    set(i, v, 0, 0, sz);
    return;
  }

  item calc_range(int l, int r, int x, int lx, int rx) {

    // Case 1: segment outside l, r
    if (lx >= r || rx <= l)
      return NEUTRAL_ELEMENT; // Neutral Element
    // Case 2: segment completely inside l, r
    if (lx >= l && rx <= r)
      return values[x];
    // Case 3: segment partly inside, partly outside l, r

    int m = lx + (rx - lx) / 2;

    item left = calc_range(l, r, 2 * x + 1, lx, m);
    item right = calc_range(l, r, 2 * x + 2, m, rx);

    //-----<Do associative operation>-----//
    return merge(left, right);
    //-----</Do associative operation>-----//
  }

  item calc_range(int l, int r) { return calc_range(l, r, 0, 0, sz); }
};

int main(void) {
  FAST int n, m;
  cin >> n >> m;
  vector<int> a(n), last(MAXN, -1), ans(m);
  vector<pair<pair<int, int>, int>> q(m);

  SegTree st;
  st.init(MAXN);

  for (int &t : a)
    cin >> t;

  for (int i = 0; i < m; i++) {
    int l, r;
    cin >> l >> r;
    l--;
    r--;
    q[i] = {{r, l}, i};
  }

  sort(q.begin(), q.end());
  int pos = 0;

  for (int i = 0; i < n; i++) {
    if (last[a[i]] >= 0) {
      st.set(last[a[i]], 0);
      st.set(i, 1);
      last[a[i]] = i;
    } else {
      st.set(i, 1);
      last[a[i]] = i;
    }
    while (q[pos].first.first == i) {
      ans[q[pos].second] =
          st.calc_range(q[pos].first.second, q[pos].first.first + 1).sum;
      pos++;
    }
  }
  for (int i : ans)
    cout << i << '\\n';

  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>

#define ull unsigned long long
#define ll long long
#define pb push_back
#define pii pair<int, int>
#define FAST                                                                   \\
  ios_base::sync_with_stdio(0);                                                \\
  cin.tie(0);                                                                  \\
  cout.tie(0);

using namespace std;

const int INF = 1e9 + 7;

struct item {
  unordered_set<int> colors;
};

struct SegTree {
  int sz, n;
  vector<item> values;

  //-----<Set up the neutral element, single, and merge for current item>-----//
  item NEUTRAL_ELEMENT;

  item merge(item a, item b) {
    for (int x : b.colors)
      if (a.colors.find(x) == a.colors.end())
        a.colors.insert(x);
    return a;
  }

  item single(int v) {
    v--;
    item a;
    a.colors.insert(v);
    return a;
  }
  //-----</Set up the neutral element, single, and merge for current
  //item>-----//

  void init(int n) {
    sz = 1;
    while (sz < n)
      sz *= 2;
    // values.assign(sz*2, NEUTRAL_ELEMENT);
    values.resize(2 * sz);
    return;
  }

  void build(vector<int> &a, int x, int lx, int rx) {

    if (rx - lx == 1) {
      if (lx < n)
        values[x] = single(a[lx]);
      return;
    }

    int m = lx + (rx - lx) / 2;
    build(a, 2 * x + 1, lx, m);
    build(a, 2 * x + 2, m, rx);

    //-----<Do associative operation>-----//
    values[x] = merge(values[2 * x + 1], values[2 * x + 2]);
    //-----</Do associative operation>-----//
  }

  void build(vector<int> &a) {
    n = a.size();
    build(a, 0, 0, sz);
    return;
  }

  item calc_range(int l, int r, int x, int lx, int rx) {

    // Case 1: segment outside l, r
    if (lx >= r || rx <= l)
      return NEUTRAL_ELEMENT; // Neutral Element
    // Case 2: segment completely inside l, r
    if (lx >= l && rx <= r)
      return values[x];
    // Case 3: segment partly inside, partly outside l, r

    int m = lx + (rx - lx) / 2;

    item left = calc_range(l, r, 2 * x + 1, lx, m);
    item right = calc_range(l, r, 2 * x + 2, m, rx);

    //-----<Do associative operation>-----//
    return merge(left, right);
    //-----</Do associative operation>-----//
  }

  item calc_range(int l, int r) { return calc_range(l, r, 0, 0, sz); }
};

int main(void) {
  FAST int n, m;
  cin >> n >> m;
  vector<int> a(n);

  SegTree st;
  st.init(n);

  for (int &t : a)
    cin >> t;
  st.build(a);

  while (m--) {
    int l, r;
    cin >> l >> r;
    l--;
    cout << st.calc_range(l, r).colors.size() << '\\n';
  }

  return 0;
}