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

#include <algorithm>
#include <functional>
#include <iostream>
#include <set>
#include <vector>
using namespace std;
using P = pair<int, int>;

template <typename T> struct BinaryIndexedTree {
  vector<T> data;

  BinaryIndexedTree(int sz) { data.assign(++sz, 0); }

  T sum(int k) {
    T ret = 0;
    for (++k; k > 0; k -= k & -k)
      ret += data[k];
    return (ret);
  }

  void add(int k, T x) {
    for (++k; k < data.size(); k += k & -k)
      data[k] += x;
  }
};

set<int> segmerge(const set<int> a, const set<int> b) {
  set<int> c = a;
  for (auto it = b.begin(); it != b.end(); ++it) {
    c.insert(*it);
  }
  return c;
}

int main() {
  int n, q;
  cin >> n >> q;
  vector<int> c(n + 1);
  for (int i = 1; i <= n; i++) {
    cin >> c[i];
  }
  vector<pair<P, int>> query(q);
  for (int i = 0; i < q; i++) {
    cin >> query[i].first.second >> query[i].first.first;
    query[i].second = i;
  }
  sort(query.begin(), query.end());
  BinaryIndexedTree<int> BIT(n + 1);
  vector<int> col(n + 1, -1);
  vector<int> ans(q);
  int nowq = 0;
  for (int i = 1; i <= n; i++) {
    if (col[c[i]] == -1) {
      col[c[i]] = i;
      BIT.add(i, 1);
    } else {
      BIT.add(col[c[i]], -1);
      col[c[i]] = i;
      BIT.add(i, 1);
    }
    while (nowq < q && i == query[nowq].first.first) {
      int l = query[nowq].first.second;
      int r = query[nowq].first.first;
      int num = query[nowq].second;
      ans[num] = BIT.sum(r) - BIT.sum(l - 1);
      nowq++;
    }
  }
  for (auto a : ans)
    cout << a << endl;
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <functional>
#include <iostream>
#include <set>
#include <vector>
using namespace std;

template <typename Monoid> struct SegmentTree {
  using F = function<Monoid(Monoid, Monoid)>;

  int sz;
  vector<Monoid> seg;

  const F f;
  const Monoid M1;

  SegmentTree(int n, const F f, const Monoid &M1) : f(f), M1(M1) {
    sz = 1;
    while (sz < n)
      sz <<= 1;
    seg.assign(2 * sz, M1);
  }

  void set(int k, const Monoid &x) { seg[k + sz] = x; }

  void build() {
    for (int k = sz - 1; k > 0; k--) {
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
    }
  }

  void update(int k, const Monoid &x) {
    k += sz;
    seg[k] = x;
    while (k >>= 1) {
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
    }
  }

  Monoid query(int a, int b) {
    Monoid L = M1, R = M1;
    for (a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
      if (a & 1)
        L = f(L, seg[a++]);
      if (b & 1)
        R = f(seg[--b], R);
    }
    return f(L, R);
  }

  Monoid operator[](const int &k) const { return seg[k + sz]; }

  template <typename C>
  int find_subtree(int a, const C &check, Monoid &M, bool type) {
    while (a < sz) {
      Monoid nxt = type ? f(seg[2 * a + type], M) : f(M, seg[2 * a + type]);
      if (check(nxt))
        a = 2 * a + type;
      else
        M = nxt, a = 2 * a + 1 - type;
    }
    return a - sz;
  }

  template <typename C> int find_first(int a, const C &check) {
    Monoid L = M1;
    if (a <= 0) {
      if (check(f(L, seg[1])))
        return find_subtree(1, check, L, false);
      return -1;
    }
    int b = sz;
    for (a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
      if (a & 1) {
        Monoid nxt = f(L, seg[a]);
        if (check(nxt))
          return find_subtree(a, check, L, false);
        L = nxt;
        ++a;
      }
    }
    return -1;
  }

  template <typename C> int find_last(int b, const C &check) {
    Monoid R = M1;
    if (b >= sz) {
      if (check(f(seg[1], R)))
        return find_subtree(1, check, R, true);
      return -1;
    }
    int a = sz;
    for (b += sz; a < b; a >>= 1, b >>= 1) {
      if (b & 1) {
        Monoid nxt = f(seg[--b], R);
        if (check(nxt))
          return find_subtree(b, check, R, true);
        R = nxt;
      }
    }
    return -1;
  }
};

set<int> segmerge(const set<int> a, const set<int> b) {
  set<int> c = a;
  for (auto it = b.begin(); it != b.end(); ++it) {
    c.insert(*it);
  }
  return c;
}

int main() {
  int n, q;
  cin >> n >> q;
  vector<int> c(n + 1);
  set<int> e;
  SegmentTree<set<int>> seg(n + 3, segmerge, e);
  for (int i = 1; i <= n; i++) {
    cin >> c[i];
    set<int> s;
    s.insert(c[i]);
    seg.set(i, s);
  }
  seg.build();
  vector<int> l(q), r(q);
  for (int i = 0; i < q; i++) {
    cin >> l[i] >> r[i];
  }

  for (int i = 0; i < q; i++) {
    int ans = seg.query(l[i], r[i] + 1).size();
    cout << ans << endl;
  }
  return 0;
}