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

// segment tree (abstract version)

#include <bits/stdc++.h>

#define rep(i, n) for (int i = 0; i < (n); i++)

using namespace std;

template <class T> class add_monoid {
  T a;

public:
  add_monoid(const T &val = T()) : a(val) {}
  static add_monoid unit() { return add_monoid(); }
  add_monoid operator*(const add_monoid &x) const { return a + x.a; }
  T &get() { return a; }
};

template <class T> class sequence_monoid {
  vector<T> a;

public:
  sequence_monoid() {}
  sequence_monoid(const T &val) : a(1, val) {}
  sequence_monoid(const vector<T> &x) : a(x) { sort(a.begin(), a.end()); }
  static sequence_monoid unit() { return sequence_monoid(); }
  sequence_monoid operator*(const sequence_monoid &x) const {
    vector<T> res;
    merge(a.begin(), a.end(), x.a.begin(), x.a.end(), back_inserter(res));
    return res;
  }
  int lower_bound(const T &val) const {
    return std::lower_bound(a.begin(), a.end(), val) - a.begin();
  }
};

template <class M> class segment_tree {
  int sz;
  vector<M> seg;

public:
  segment_tree() {}
  segment_tree(int n) { build(n); }
  segment_tree(const vector<M> &a) { build(a); }
  void build(int n) {
    for (sz = 1; sz < n; sz <<= 1)
      ;
    seg.assign(2 * sz, M::unit());
  }
  void build(const vector<M> &a) {
    int n = a.size();
    build(n);
    rep(i, n) seg[sz + i] = a[i];
    for (int i = sz - 1; i > 0; i--) {
      seg[i] = seg[2 * i] * seg[2 * i + 1];
    }
  }
  template <class N, class F> N query(int l, int r, const F &f) {
    N lcum = N::unit(), rcum = N::unit();
    for (int a = l + sz, b = r + sz; a < b; a >>= 1, b >>= 1) {
      if (a & 1)
        lcum = lcum * f(seg[a++]);
      if (b & 1)
        rcum = f(seg[--b]) * rcum;
    }
    return lcum * rcum;
  }
};

int main() {
  int n, q;
  scanf("%d%d", &n, &q);
  vector<int> a(n);
  rep(i, n) scanf("%d", &a[i]), a[i]--;

  vector<sequence_monoid<int>> x(n);
  vector<int> pre(n, -1);
  rep(i, n) {
    x[i] = pre[a[i]];
    pre[a[i]] = i;
  }

  segment_tree<sequence_monoid<int>> S(x);
  rep(_, q) {
    int l, r;
    scanf("%d%d", &l, &r);
    l--;
    auto ans = S.query<add_monoid<int>>(
        l, r, [&](const sequence_monoid<int> &x) -> add_monoid<int> {
          return x.lower_bound(l);
        });
    printf("%d\\n", ans.get());
  }

  return 0;
}


Error: TLE

Fixed submission:

// segment tree (abstract version)

#include <bits/stdc++.h>

#define rep(i, n) for (int i = 0; i < (n); i++)

using namespace std;

template <class T> class add_monoid {
  T a;

public:
  add_monoid(const T &val = T()) : a(val) {}
  static add_monoid unit() { return add_monoid(); }
  add_monoid operator*(const add_monoid &x) const { return a + x.a; }
  int to_int() const { return int(a); }
};

template <class T> class sequence_monoid {
  vector<T> a;

public:
  sequence_monoid() {}
  sequence_monoid(const T &val) : a(1, val) {}
  sequence_monoid(const vector<T> &x) : a(x) { sort(a.begin(), a.end()); }
  static sequence_monoid unit() { return sequence_monoid(); }
  sequence_monoid operator*(const sequence_monoid &x) const {
    vector<T> res;
    merge(a.begin(), a.end(), x.a.begin(), x.a.end(), back_inserter(res));
    return res;
  }
  int lower_bound(const T &val) const {
    return std::lower_bound(a.begin(), a.end(), val) - a.begin();
  }
};

template <class M> class segment_tree {
  int sz;
  vector<M> seg;

public:
  segment_tree() {}
  segment_tree(int n) { build(n); }
  segment_tree(const vector<M> &a) { build(a); }
  void build(int n) {
    for (sz = 1; sz < n; sz <<= 1)
      ;
    seg.assign(2 * sz, M::unit());
  }
  void build(const vector<M> &a) {
    int n = a.size();
    build(n);
    rep(i, n) seg[sz + i] = a[i];
    for (int i = sz - 1; i > 0; i--) {
      seg[i] = seg[2 * i] * seg[2 * i + 1];
    }
  }
  template <class N> N query(int l, int r, const function<N(M)> &f) {
    N lcum = N::unit(), rcum = N::unit();
    for (int a = l + sz, b = r + sz; a < b; a >>= 1, b >>= 1) {
      if (a & 1)
        lcum = lcum * f(seg[a++]);
      if (b & 1)
        rcum = f(seg[--b]) * rcum;
    }
    return lcum * rcum;
  }
};

int main() {
  int n, q;
  scanf("%d%d", &n, &q);
  vector<int> a(n);
  rep(i, n) scanf("%d", &a[i]), a[i]--;

  vector<sequence_monoid<int>> x(n);
  vector<int> pre(n, -1);
  rep(i, n) {
    x[i] = pre[a[i]];
    pre[a[i]] = i;
  }

  segment_tree<sequence_monoid<int>> S(x);
  rep(_, q) {
    int l, r;
    scanf("%d%d", &l, &r);
    l--;
    auto ans = S.query<add_monoid<int>>(
        l, r, [&](const sequence_monoid<int> &x) { return x.lower_bound(l); });
    printf("%d\\n", ans.to_int());
  }

  return 0;
}