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

/*** author: yuji9511 ***/
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using lpair = pair<ll, ll>;
const ll MOD = 1e9 + 7;
const ll INF = 1e18;
#define rep(i, m, n) for (ll i = (m); i < (n); i++)
#define rrep(i, m, n) for (ll i = (m); i >= (n); i--)
#define printa(x, n)                                                           \\
  for (ll i = 0; i < n; i++) {                                                 \\
    cout << (x[i]) << " \\n"[i == n - 1];                                       \\
  };
void print() {}
template <class H, class... T> void print(H &&h, T &&...t) {
  cout << h << " \\n"[sizeof...(t) == 0];
  print(forward<T>(t)...);
}
typedef struct {
  ll l;
  ll r;
  ll idx;
} P;

struct BIT { // 1-indexed
private:
  int n, n2;
  vector<ll> bit;

public:
  BIT(ll N) {
    n = N;
    bit.assign(n + 1, 0);
    n2 = 1;
    while (n2 * 2 <= n)
      n2 *= 2;
  }

  ll sum(ll x) { //[1, x]
    ll res = 0;
    for (ll i = x; i > 0; i -= i & -i)
      res += bit[i];
    return res;
  }

  ll sum(ll lv, ll rv) { // [lv, rv)
    return sum(rv - 1) - sum(lv - 1);
  }

  void add(ll x, ll v) {
    if (x == 0)
      return;
    for (ll i = x; i <= n; i += i & -i)
      bit[i] += v;
  }

  ll lower_bound(ll w) {
    if (w <= 0)
      return 0;
    ll x = 0;
    for (ll k = n2; k > 0; k /= 2) {
      if (x + k <= n && bit[x + k] < w) {
        w -= bit[x + k];
        x += k;
      }
    }
    return x + 1;
  }
};
ll ans[500010] = {};
ll last_pos[500010] = {};
ll c[500010];
void solve() {
  ll N, Q;
  cin >> N >> Q;
  rep(i, 0, N) cin >> c[i];
  vector<P> vp;
  rep(i, 0, Q) {
    ll l, r;
    cin >> l >> r;
    vp.push_back({l, r, i});
  }
  sort(vp.begin(), vp.end(), [](P p1, P p2) { return p1.r < p2.r; });
  rep(i, 0, N + 1) last_pos[i] = -1;
  // rep(i,0,N){
  //     last_pos[c[i]] = i;
  // }
  BIT bit(N + 10);
  // ll r0 = vp[0].r;
  ll cur_r = 1;
  rep(i, 0, Q) {
    ll l = vp[i].l, r = vp[i].r, idx = vp[i].idx;
    rep(j, cur_r, r + 1) {
      ll cur = last_pos[c[j - 1]];
      if (cur != -1) {
        bit.add(cur, -1);
      }
      last_pos[c[j - 1]] = j;
      bit.add(j, 1);
    }
    cur_r = r + 1;
    ll res = bit.sum(l, r + 1);
    ans[idx] = res;
    // rep(i,1,N+1){
    //     cout << bit.sum(i,i+1) << " ";
    // }
    // cout << endl;
  }
  rep(i, 0, Q) { print(ans[i]); }
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  solve();
}

Error: TLE

Fixed submission:

/*** author: yuji9511 ***/
#include <bits/stdc++.h>
using namespace std;
#define rep(i, m, n) for (int i = (m); i < (n); i++)
#define rrep(i, m, n) for (int i = (m); i >= (n); i--)
#define printa(x, n)                                                           \\
  for (int i = 0; i < n; i++) {                                                \\
    cout << (x[i]) << " \\n"[i == n - 1];                                       \\
  };
void print() {}
template <class H, class... T> void print(H &&h, T &&...t) {
  cout << h << " \\n"[sizeof...(t) == 0];
  print(forward<T>(t)...);
}
struct Mo {
  using ADD = function<void(int)>;
  using DEL = function<void(int)>;
  using REM = function<void(int)>;

  int width;
  vector<int> left, right, order;
  vector<bool> v;

  Mo(int N, int Q) : width((int)sqrt(N)), order(Q), v(N) {
    iota(begin(order), end(order), 0);
  }

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

  void run(const ADD &add, const DEL &del, const REM &rem) {
    assert(left.size() == order.size());
    sort(begin(order), end(order), [&](int a, int b) {
      int ablock = left[a] / width, bblock = left[b] / width;
      if (ablock != bblock)
        return ablock < bblock;
      if (ablock & 1)
        return right[a] < right[b];
      return right[a] > right[b];
    });
    int nl = 0, nr = 0;
    auto push = [&](int idx) {
      v[idx].flip();
      if (v[idx])
        add(idx);
      else
        del(idx);
    };
    for (auto idx : order) {
      while (nl > left[idx])
        push(--nl);
      while (nr < right[idx])
        push(nr++);
      while (nl < left[idx])
        push(nl++);
      while (nr > right[idx])
        push(--nr);
      rem(idx);
    }
  }
};

void solve() {
  int N, Q;
  cin >> N >> Q;
  vector<int> A(N);
  for (int i = 0; i < N; i++) {
    cin >> A[i];
  }
  vector<int> f(500001);
  Mo mo(N, Q);
  for (int i = 0; i < Q; i++) {
    int l, r;
    cin >> l >> r;
    mo.add(--l, r);
  }
  int ret = 0;
  auto add = [&](int idx) {
    if (f[A[idx]]++ == 0)
      ret++;
  };
  auto del = [&](int idx) {
    if (f[A[idx]]-- == 1)
      --ret;
  };
  vector<int> ans(Q);
  auto rem = [&](int idx) { ans[idx] = ret; };
  mo.run(add, del, rem);
  for (int i = 0; i < Q; i++) {
    cout << ans[i] << "\\n";
  }
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  solve();
}