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

#include <bits/stdc++.h>
using Int = long long; // clang-format off
#define REP_(i, a_, b_, a, b, ...) for (Int i = (a), lim##i = (b); i < lim##i; i++)
#define REP(i, ...) REP_(i, __VA_ARGS__, __VA_ARGS__, 0, __VA_ARGS__)
#define ALL(v) std::begin(v), std::end(v)
struct SetupIO { SetupIO() { std::cin.tie(nullptr), std::ios::sync_with_stdio(false), std::cout << std::fixed << std::setprecision(13); } } setup_io;
#ifndef dump
#define dump(...)
#endif // clang-format on

/**
 *    author:  knshnb
 *    created: Sun Aug  9 02:49:18 JST 2020
 **/

int popcount(std::uint32_t x) { return __builtin_popcount(x); }
int popcount(std::uint64_t x) { return __builtin_popcountll(x); }

template <class block_type = std::uint64_t> struct BitVector {
  static constexpr int b = sizeof(block_type) * CHAR_BIT; // blockのサイズ
  int n;
  std::vector<block_type> bit;
  std::vector<int> acc;
  BitVector() {}
  BitVector(int n_) : n(n_), bit(n / b + 1), acc(n / b + 1) {}
  template <bool x = 1> void set(int i) {
    if (x)
      bit[i / b] |= (block_type)1 << (i % b);
    else
      bit[i / b] &= ~((block_type)1 << (i % b));
  }
  void build() {
    for (int i = 0; i < (int)acc.size() - 1; i++) {
      acc[i + 1] = acc[i] + popcount(bit[i]);
    }
  }
  // [0, i)内のxの個数
  template <bool x> int rank(int i) {
    if (x)
      return acc[i / b] + (i % b ? popcount(bit[i / b] << (b - i % b)) : 0);
    else
      return i - rank<true>(i);
  }
  // j番目のxのindex
  template <bool x> int select(int j) {
    int ok = n, ng = -1;
    while (std::abs(ok - ng) > 1) {
      int mid = (ok + ng) / 2;
      (rank<x>(mid + 1, x) > j ? ok : ng) = mid;
    }
    return ok;
  }
};

template <class T, int maxlog = 31, class block_type = std::uint64_t>
struct WaveletMatrix {
  using bv_type = BitVector<block_type>;
  std::array<bv_type, maxlog> bvs; // [maxlog, n]の01行列
  std::array<int, maxlog> offset = {}; // 各列でbitが0になっている要素の数

  WaveletMatrix(const std::vector<T> &a) {
    std::vector<T> cur_data = a;
    for (int k = maxlog - 1; k >= 0; k--) { // 上位bitから見る
      std::vector<T> zero, one;
      bvs[k] = bv_type(a.size());
      for (int i = 0; i < a.size(); i++) {
        bool bit = cur_data[i] >> k & 1;
        if (bit)
          one.push_back(cur_data[i]), bvs[k].template set<1>(i);
        else
          zero.push_back(cur_data[i]);
      }
      offset[k] = zero.size();
      cur_data = std::move(zero);
      cur_data.insert(cur_data.end(), one.begin(), one.end());
      bvs[k].build();
    }
  }
  // [l, r)の{x未満の個数, xの個数, xより大の個数}
  std::array<int, 3> rank_3way(int l, int r, int x) {
    int lt = 0, eq = r - l, gt = 0;
    for (int k = maxlog - 1; k >= 0; k--) {
      int prv_num = r - l;
      if (x >> k & 1) {
        l = offset[k] + bvs[k].template rank<1>(l);
        r = offset[k] + bvs[k].template rank<1>(r);
        lt += prv_num - (r - l);
      } else {
        l = bvs[k].template rank<0>(l);
        r = bvs[k].template rank<0>(r);
        gt += prv_num - (r - l);
      }
      eq -= prv_num - (r - l);
    }
    return {lt, eq, gt};
  }
  // [l, r)内の(小さい方から)j番目(0-index)の数
  int quantile(int l, int r, int j) {
    T ret = 0;
    for (int k = maxlog - 1; k >= 0; k--) {
      int zl = bvs[k].template rank<0>(l);
      int zr = bvs[k].template rank<0>(r);
      if (zr - zl > j) { // kビット目は0
        l = zl;
        r = zr;
      } else { // kビット目は1
        l = offset[k] + (l - zl);
        r = offset[k] + (r - zr);
        ret |= (T)1 << k;
        j -= zr - zl;
      }
    }
    return ret;
  }
};

signed main() {
  int n, Q;
  std::cin >> n >> Q;
  std::vector<int> prv(n + 1), tmp(n);
  REP(i, 1, n + 1) {
    int c;
    std::cin >> c, c--;
    prv[i] = tmp[c];
    tmp[c] = i;
  }
  WaveletMatrix wm(prv);
  REP(q, Q) {
    int l, r;
    std::cin >> l >> r, r++;
    std::cout << wm.rank_3way(l, r, l)[0] << "\\n";
  }
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using Int = long long; // clang-format off
#define REP_(i, a_, b_, a, b, ...) for (Int i = (a), lim##i = (b); i < lim##i; i++)
#define REP(i, ...) REP_(i, __VA_ARGS__, __VA_ARGS__, 0, __VA_ARGS__)
#define ALL(v) std::begin(v), std::end(v)
struct SetupIO { SetupIO() { std::cin.tie(nullptr), std::ios::sync_with_stdio(false), std::cout << std::fixed << std::setprecision(13); } } setup_io;
#ifndef dump
#define dump(...)
#endif // clang-format on

/**
 *    author:  knshnb
 *    created: Sun Aug  2 21:38:01 JST 2020
 **/

struct Mo {
  struct Query {
    int l, r, idx;
    Query(int l_, int r_, int idx_) : l(l_), r(r_), idx(idx_) {}
  };
  int width;
  std::vector<Query> query;
  std::vector<bool> v;

  // widthは指定しないと自動でsqrt(n)にする
  Mo(int n, int width_ = -1)
      : width(width == -1 ? (int)sqrt(n) : width_), v(n) {}
  void add(int l, int r) {
    int idx = query.size();
    query.emplace_back(l, r, idx);
  }
  template <class F, class G, class H>
  void run(const F &add, const G &del, const H &rem) {
    std::sort(query.begin(), query.end(), [&](const Query &a, const Query &b) {
      int ablock = a.l / width, bblock = b.l / width;
      if (ablock != bblock)
        return ablock < bblock;
      return a.r > b.r;
      // if (ablock & 1) return a.r < b.r;
      // return a.r > b.r;
    });
    int nl = 0, nr = 0;
    auto push = [&](int idx) {
      v[idx].flip();
      if (v[idx])
        add(idx);
      else
        del(idx);
    };
    for (Query &q : query) {
      while (nl > q.l)
        push(--nl);
      while (nr < q.r)
        push(nr++);
      while (nl < q.l)
        push(nl++);
      while (nr > q.r)
        push(--nr);
      rem(q.idx);
      while (nl > q.l)
        push(--nl);
    }
  }
};

signed main() {
  Int n, Q;
  std::cin >> n >> Q;
  std::vector<Int> a(n);
  REP(i, n) std::cin >> a[i];
  Mo mo(n);
  REP(q, Q) {
    Int l, r;
    std::cin >> l >> r, l--;
    mo.add(l, r);
  }
  Int cur = 0;
  std::vector<Int> cnt(n), ans(Q);
  mo.run(
      [&](Int i) {
        if (cnt[a[i]]++ == 0)
          cur++;
      },
      [&](Int i) {
        if (--cnt[a[i]] == 0)
          cur--;
      },
      [&](Int i) { ans[i] = cur; });
  REP(q, Q) std::cout << ans[q] << "\\n";
}