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

#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;

const int MAX = 1000001;

// structure to store queries
struct Query {
  int l, r, idx;
};

// cmp function to sort queries according to r
bool cmp(Query x, Query y) { return x.r < y.r; }

// updating the bit array
void update(int idx, int val, vector<int> &bit, int n) {
  for (; idx <= n; idx += idx & -idx)
    bit[idx] += val;
}

// querying the bit array
int query(int idx, vector<int> &bit) {
  int sum = 0;
  for (; idx > 0; idx -= idx & -idx)
    sum += bit[idx];
  return sum;
}

void answeringQueries(vector<int> &arr, int n, vector<Query> &queries, int q) {
  // initialising bit array
  vector<int> bit(n + 1);

  // holds the rightmost index of any number
  // as numbers of a[i] are less than or equal to 10^6
  vector<int> last_visit(MAX, -1);

  // answer for each query
  vector<int> ans(q);
  int query_counter = 0;
  for (int i = 0; i < n; i++) {
    // If last visit is not -1 update -1 at the
    // idx equal to last_visit[arr[i]]
    if (last_visit[arr[i]] != -1)
      update(last_visit[arr[i]] + 1, -1, bit, n);

    // Setting last_visit[arr[i]] as i and updating
    // the bit array accordingly
    last_visit[arr[i]] = i;
    update(i + 1, 1, bit, n);

    // If i is equal to r of any query store answer
    // for that query in ans[]
    while (query_counter < q && queries[query_counter].r == i) {
      ans[queries[query_counter].idx] =
          query(queries[query_counter].r + 1, bit) -
          query(queries[query_counter].l, bit);
      query_counter++;
    }
  }

  // print answer for each query
  for (int i = 0; i < q; i++)
    cout << ans[i] << endl;
}

// driver code
int main() {
  int n, q;
  cin >> n >> q;
  vector<int> c(n);
  for (int i = 0; i < n; i++)
    cin >> c[i];
  vector<Query> queries(q);
  for (int i = 0; i < q; i++) {
    int l, r;
    cin >> l >> r;
    queries[i] = {l - 1, r - 1, i};
  }

  sort(queries.begin(), queries.end(), cmp);
  answeringQueries(c, n, queries, q);
  return 0;
}

Error: TLE

Fixed submission:

#include <iostream>
#include <set>
#include <vector>

using namespace std;

struct SegmentTree {
private:
  //////////////////////
  // TODO Change them //
  //////////////////////
  const set<int> CALCULATE_IDENTITY_ELEMENT = set<int>{};

  static set<int> calculate(set<int> x, set<int> y) {
    if (x.size() < y.size()) {
      for (auto &a : x)
        y.insert(a);
      return y;
    } else {
      for (auto &a : y)
        x.insert(a);
      return x;
    }
  }
  //////////////////////
  // TODO Change them //
  //////////////////////

  int n;
  vector<set<int>> data;

  void initialize(int size, vector<int> &v) {
    n = 1;
    while (n < size)
      n <<= 1;
    data.resize(2 * n);

    for (int i = n; i < n + v.size(); i++)
      data[i].insert(v[i - n]);
    for (int i = n - 1; i > 0; i--)
      data[i] = children(i);
  }

  set<int> children(int index) {
    return calculate(data[index * 2], data[index * 2 + 1]);
  }

  set<int> query(int wantL, int wantR, int index, int nowL, int nowR) {
    if (nowR <= wantL || wantR <= nowL)
      return CALCULATE_IDENTITY_ELEMENT;

    if (wantL <= nowL && nowR <= wantR)
      return data[index];
    else {
      int mid = (nowL + nowR) / 2;
      set<int> valueL = query(wantL, wantR, index * 2, nowL, mid);
      set<int> valueR = query(wantL, wantR, index * 2 + 1, mid, nowR);
      return calculate(valueL, valueR);
    }
  }

public:
  SegmentTree(vector<int> &v) { initialize(v.size(), v); }

  set<int> get(int indexL, int indexR) {
    return query(indexL, indexR, 1, 0, n);
  }
};

int main() {
  int n, q;
  cin >> n >> q;
  vector<int> c(n);
  for (int i = 0; i < n; i++)
    cin >> c[i];

  SegmentTree seg(c);
  for (int i = 0; i < q; i++) {
    int l, r;
    cin >> l >> r;
    cout << seg.get(l - 1, r).size() << endl;
  }
  return 0;
}