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

#include <bits/stdc++.h>
using namespace std;

// boost
#include <boost/multiprecision/cpp_int.hpp>
using boost::multiprecision::cpp_int;

using ll = long long;
using ld = long double;

using vi = vector<int>;
using vvi = vector<vi>;
using vll = vector<ll>;
using vvll = vector<vll>;
using vb = vector<bool>;
using vs = vector<string>;
using vld = vector<ld>;
using vvld = vector<vld>;

typedef pair<ll, ll> P;

#define bit(n) (1LL << (n))

// #define int long long

#define all(v) v.begin(), v.end()

#define rep(i, n) for (ll i = 0; i < n; i++)
#define REP(i, n) for (ll i = 1; i < n; i++)

#define FOR(i, a, b) for (ll i = (a); i < (b); i++)
#define FORm(i, m) for (auto i = m.begin(); i != m.end(); i++)

template <class T> inline void chmax(T &a, T b) { a = std::max(a, b); }
template <class T> inline void chmin(T &a, T b) { a = std::min(a, b); }

#define mod (ll)(1e9 + 7)
// #define mod (998244353ll)

const long long INF = 1LL << 60;

template <typename T> class SegTree {
  int n;
  vector<T> data;
  T default_value;
  function<T(T a, T b)> operation;
  function<T(T prev_val, T new_val)> _update;

  // [a,b)
  T query(int a, int b, int k, int l, int r) {
    if (r <= a || b <= l) {
      return default_value;
    }

    if (a <= l && r <= b) {
      return data[k];
    } else {
      T vl = query(a, b, 2 * k + 1, l, (l + r) / 2);
      T vr = query(a, b, 2 * k + 2, (l + r) / 2, r);
      return operation(vl, vr);
    }
  }

public:
  SegTree(int _n, T _default_value, function<T(T a, T b)> _operation,
          function<T(T prev_val, T new_val)> update_function)
      : default_value(_default_value), operation(_operation),
        _update(update_function) {
    n = 1;
    while (n < _n) {
      n <<= 1;
    }
    data = vector<T>(2 * n - 1, default_value);
  }

  SegTree(vector<T> initial_value, T _default_value,
          function<T(T a, T b)> _operation,
          function<T(T prev_val, T new_val)> update_function)
      : default_value(_default_value), operation(_operation),
        _update(update_function) {
    ll sz = initial_value.size();
    n = 1;
    while (n < sz) {
      n <<= 1;
    }
    data = vector<T>(2 * n - 1, default_value);
    for (int i = 0; i < sz; i++) {
      data[n - 1 + i] = initial_value[i];
    }
    for (int i = n - 2; i >= 0; i--) {
      data[i] = operation(data[i * 2 + 1], data[i * 2 + 2]);
    }
  }

  // update i-th value (0-indexed)
  void update(int i, T x) {
    i += n - 1;
    data[i] = _update(data[i], x);
    while (i > 0) {
      i = (i - 1) / 2;
      data[i] = operation(data[i * 2 + 1], data[i * 2 + 2]);
    }
  }

  // execute query of section [a, b)
  T query(int a, int b) { return query(a, b, 0, 0, n); }

  // get i-th value
  T operator[](int i) { return data[i + n - 1]; }
};

signed main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(20);

  ll n, q;
  cin >> n >> q;

  vll c(n);
  vll pre(n, -1);
  vll pi(n, -1);

  rep(i, n) {
    cin >> c[i];
    c[i]--;
    pre[i] = pi[c[i]];
    pi[c[i]] = i;
  }

  using tup = tuple<ll, ll, ll>;
  vector<tup> questions;
  rep(i, q) {
    ll l, r;
    cin >> l >> r;
    l--;
    r--;
    questions.emplace_back(r, l, i);
  }

  sort(all(questions));
  reverse(all(questions));

  SegTree<ll> st(
      n, 0ll, [](ll a, ll b) { return a + b; },
      [](ll prev_val, ll new_val) { return new_val; });

  rep(i, n) {
    if (pi[i] != -1) {
      st.update(pi[i], 1);
    }
  }

  auto itr = questions.begin();

  vll ans(q);

  for (int r = n - 1; r >= 0; r--) {
    while (1) {
      if (itr == questions.end())
        break;
      ll ql = get<1>(*itr);
      ll qr = get<0>(*itr);
      ll qi = get<2>(*itr);
      if (r != qr)
        break;

      // solve
      ans[qi] = st.query(ql, qr + 1);

      itr++;
    }

    // st.update(r, 0);
    if (pre[r] >= 0)
      st.update(pre[r], 1);
  }

  for (auto it : ans) {
    cout << it << "\\n";
  }

  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

// boost
#include <boost/multiprecision/cpp_int.hpp>
using boost::multiprecision::cpp_int;

using ll = long long;
using ld = long double;

using vi = vector<int>;
using vvi = vector<vi>;
using vll = vector<ll>;
using vvll = vector<vll>;
using vb = vector<bool>;
using vs = vector<string>;
using vld = vector<ld>;
using vvld = vector<vld>;

typedef pair<ll, ll> P;

#define bit(n) (1LL << (n))

// #define int long long

#define all(v) v.begin(), v.end()

#define rep(i, n) for (ll i = 0; i < n; i++)
#define REP(i, n) for (ll i = 1; i < n; i++)

#define FOR(i, a, b) for (ll i = (a); i < (b); i++)
#define FORm(i, m) for (auto i = m.begin(); i != m.end(); i++)

template <class T> inline void chmax(T &a, T b) { a = std::max(a, b); }
template <class T> inline void chmin(T &a, T b) { a = std::min(a, b); }

#define mod (ll)(1e9 + 7)
// #define mod (998244353ll)

const long long INF = 1LL << 60;

struct Mo {
  vector<int> left, right, order;
  vector<bool> v;
  int width;
  int nl, nr, ptr;

  Mo(int n) : width(min(n / 2, 1000)), nl(0), nr(0), ptr(0), v(n) {
    left.reserve((ll)5e5 + 10);
    right.reserve((ll)5e5 + 10);
    order.reserve((ll)5e5 + 10);
  }

  void insert(int l, int r) /* [l, r) */
  {
    left.push_back(l);
    right.push_back(r);
  }

  /* ソート */
  void build() {
    order.resize(left.size());
    iota(begin(order), end(order), 0);
    sort(begin(order), end(order), [&](int a, int b) {
      if (left[a] / width != left[b] / width)
        return left[a] < left[b];
      return right[a] < right[b];
    });
  }

  /* クエリを 1 つぶんすすめて, クエリのidを返す */
  int process() {
    if (ptr == order.size())
      return (-1);
    const auto id = order[ptr];
    while (nl > left[id])
      distribute(--nl);
    while (nr < right[id])
      distribute(nr++);
    while (nl < left[id])
      distribute(nl++);
    while (nr > right[id])
      distribute(--nr);
    return (order[ptr++]);
  }

  inline void distribute(int idx) {
    v[idx].flip();
    if (v[idx])
      add(idx);
    else
      del(idx);
  }

  void add(int idx);

  void del(int idx);
};

int N, A[500000], Q;
int ans[500000];
int cnt[500000], sum;

void Mo::add(int idx) {
  if (cnt[A[idx]]++ == 0)
    ++sum;
}

void Mo::del(int idx) {
  if (--cnt[A[idx]] == 0)
    --sum;
}

int main() {
  scanf("%d", &N);
  scanf("%d", &Q);
  for (int i = 0; i < N; i++) {
    scanf("%d", &A[i]);
  }
  Mo mo(N);
  for (int i = 0; i < Q; i++) {
    int a, b;
    scanf("%d %d", &a, &b);
    mo.insert(--a, b);
  }
  mo.build();
  for (int i = 0; i < Q; i++) {
    int idx = mo.process();
    ans[idx] = sum;
  }
  for (int i = 0; i < Q; i++) {
    printf("%d\\n", ans[i]);
  }
}