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

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i, n) for (ll i = 0, i##_len = (n); i < i##_len; i++)
#define reps(i, s, n) for (ll i = (s), i##_len = (n); i < i##_len; i++)
#define rrep(i, n) for (ll i = (n)-1; i >= 0; i--)
#define rreps(i, e, n) for (ll i = (n)-1; i >= (e); i--)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define sz(x) ((ll)(x).size())
#define len(x) ((ll)(x).length())
#define endl "\\n"

template <class T> struct SegmentTree {
private:
  int n;
  vector<T> node;
  T def;
  function<T(T, T)> lop;
  function<T(T, T)> out;

public:
  SegmentTree() {}
  SegmentTree(const vector<T> &v, T _def, function<T(T, T)> _lop,
              function<T(T, T)> _out) {
    int vl = (int)v.size();
    n = 1;
    while (n < vl)
      n *= 2;
    def = _def;
    lop = _lop;
    out = _out;
    node = vector<T>(2 * n - 1, def);
    for (int i = 0; i < vl; i++)
      node[i + n - 1] = v[i];
    for (int i = n - 2; i >= 0; i--)
      node[i] = out(node[i * 2 + 1], node[i * 2 + 2]);
  }

  void update(int idx, T val) {
    idx += (n - 1);
    node[idx] = lop(node[idx], val);
    while (idx > 0) {
      idx = (idx - 1) / 2;
      node[idx] = out(node[idx * 2 + 1], node[idx * 2 + 2]);
    }
  }

  T query(int a, int b, int k = 0, int l = 0, int r = -1) {
    if (r < 0)
      r = n;
    if ((r <= a) || (b <= l))
      return def;
    if ((a <= l) && (r <= b))
      return node[k];
    return out(query(a, b, 2 * k + 1, l, (l + r) / 2),
               query(a, b, 2 * k + 2, (l + r) / 2, r));
  }
};

struct S {
  ll l, r, q;

  bool operator<(const S &b) const {
    if (r != b.r)
      return r < b.r;
    if (q != b.q)
      return q < b.q;
    return l < b.l;
  }
};

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  // ifstream in("input.txt");
  // cin.rdbuf(in.rdbuf());
  ll n, q;
  cin >> n >> q;
  vector<ll> c(n);
  rep(i, n) cin >> c[i];
  vector<ll> bef(n + 1, -1);
  vector<S> vs;
  rep(i, n) {
    if (bef[c[i]] != -1) {
      vs.push_back((S){bef[c[i]], i, -1});
    }
    bef[c[i]] = i;
  }
  rep(i, q) {
    ll l, r;
    cin >> l >> r;
    l--;
    r--;
    vs.push_back((S){l, r, i});
  }
  sort(all(vs));
  auto lop = [](ll a, ll b) { return a + b; };
  auto out = [](ll a, ll b) { return a + b; };
  SegmentTree<ll> st(vector<ll>(n, 0), 0, lop, out);
  vector<ll> ans(q);
  rep(i, sz(vs)) {
    if (vs[i].q == -1) {
      st.update(vs[i].l, 1);
    } else {
      ans[vs[i].q] = (vs[i].r - vs[i].l + 1) - st.query(vs[i].l, vs[i].r);
    }
  }
  rep(i, q) cout << ans[i] << endl;
  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i, n) for (ll i = 0, i##_len = (n); i < i##_len; i++)
#define reps(i, s, n) for (ll i = (s), i##_len = (n); i < i##_len; i++)
#define rrep(i, n) for (ll i = (n)-1; i >= 0; i--)
#define rreps(i, e, n) for (ll i = (n)-1; i >= (e); i--)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define sz(x) ((ll)(x).size())
#define len(x) ((ll)(x).length())
#define endl "\\n"

struct Mo {
private:
  using F = function<void(int)>;
  vector<int> ls, rs, ord;
  int n, width, nl, nr, ptr;
  F expandL, expandR;
  F shrinkL, shrinkR;

public:
  Mo(int n, int width, F expandL, F expandR, F shrinkL, F shrinkR)
      : n(n), width(width), nl(0), nr(0), ptr(0), expandL(expandL),
        expandR(expandR), shrinkL(shrinkL), shrinkR(shrinkR) {}

  Mo(int n, int width, F expand, F shrink) {
    *this = Mo(n, width, expand, expand, shrink, shrink);
  }

  void add(int l, int r) {
    ls.emplace_back(l);
    rs.emplace_back(r);
  }

  void build() {
    ord.resize(ls.size());
    iota(ord.begin(), ord.end(), 0);
    sort(ord.begin(), ord.end(), [&](int a, int b) {
      if ((ls[a] / width) != (ls[b] / width))
        return ls[a] < ls[b];
      if (rs[a] == rs[b])
        return ls[a] < ls[b];
      return bool((rs[a] < rs[b]) ^ ((ls[a] / width) & 1));
    });
  }

  int process() {
    if (ptr == (int)ord.size())
      return -1;
    const int idx = ord[ptr++];
    while (nl > ls[idx])
      expandL(--nl);
    while (nr < rs[idx])
      expandR(nr++);
    while (nl < ls[idx])
      shrinkL(nl++);
    while (nr > rs[idx])
      shrinkR(--nr);
    return idx;
  }
};

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  // ifstream in("input.txt");
  // cin.rdbuf(in.rdbuf());
  ll n, q;
  cin >> n >> q;
  vector<ll> c(n);
  rep(i, n) cin >> c[i];
  ll num = 0;
  vector<ll> cnt(n + 1, 0);
  auto expand = [&](ll k) {
    if (cnt[c[k]] == 0)
      num++;
    cnt[c[k]]++;
  };
  auto shrink = [&](ll k) {
    cnt[c[k]]--;
    if (cnt[c[k]] == 0)
      num--;
  };
  Mo mo(n, 1000, expand, shrink);
  rep(i, q) {
    ll l, r;
    cin >> l >> r;
    l--;
    mo.add(l, r);
  }
  mo.build();
  vector<ll> ans(q);
  rep(i, q) {
    ll k = mo.process();
    ans[k] = num;
  }
  rep(i, q) cout << ans[i] << endl;
  return 0;
}