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

/**
 * code generated by JHelper
 * More info: https://github.com/AlexeyDmitriev/JHelper
 * @author tatsumack
 */

#include <fstream>
#include <iostream>

#include <bits/stdc++.h>

#define int long long
#define REP(i, n) for (int i = 0, i##_len = (n); i < i##_len; ++i)
#define FOR(i, a, b) for (int i = (a), i##_len = (b); i <= i##_len; ++i)
#define REV(i, a, b) for (int i = (a); i >= (b); --i)
#define CLR(a, b) memset((a), (b), sizeof(a))
#define DUMP(x) cout << #x << " = " << (x) << endl;
#define INF 1001001001001001001ll
#define fcout cout << fixed << setprecision(12)

using namespace std;

typedef pair<int, int> P;

class FRangeSetQuery {
public:
  vector<int> c;

  template <class Abel> struct BIT {
    vector<Abel> dat[2];
    Abel UNITY_SUM = 0; // to be set

    /* [1, n] */
    BIT(int n) { init(n); }
    void init(int n) {
      for (int iter = 0; iter < 2; ++iter)
        dat[iter].assign(n + 1, UNITY_SUM);
    }

    /* a, b are 1-indexed, [a, b) */
    inline void sub_add(int p, int a, Abel x) {
      for (int i = a; i < (int)dat[p].size(); i += i & -i)
        dat[p][i] = dat[p][i] + x;
    }
    inline void add(int a, int b, Abel x) {
      sub_add(0, a, x * -(a - 1));
      sub_add(1, a, x);
      sub_add(0, b, x * (b - 1));
      sub_add(1, b, x * (-1));
    }

    /* a is 1-indexed, [a, b) */
    inline Abel sub_sum(int p, int a) {
      Abel res = UNITY_SUM;
      for (int i = a; i > 0; i -= i & -i)
        res = res + dat[p][i];
      return res;
    }
    inline Abel sum(int a, int b) {
      return sub_sum(0, b - 1) + sub_sum(1, b - 1) * (b - 1) -
             sub_sum(0, a - 1) - sub_sum(1, a - 1) * (a - 1);
    }

    /* debug */
    void print() {
      for (int i = 1; i < (int)dat[0].size(); ++i)
        cout << sum(i, i + 1) << ",";
      cout << endl;
    }
  };

  void solve(std::istream &cin, std::ostream &cout) {
    int N, Q;
    cin >> N >> Q;
    c.resize(N);
    REP(i, N) cin >> c[i];

    vector<int> lefts(Q), rights(Q), ids(Q);
    for (int i = 0; i < Q; ++i) {
      cin >> lefts[i] >> rights[i];
      --lefts[i];
      ids[i] = i;
    }
    sort(ids.begin(), ids.end(),
         [&](int i, int j) { return rights[i] < rights[j]; });

    BIT<int> bit(N + 5);
    vector<int> prev(N + 1, -1);
    vector<int> res(Q, 0);
    int r = 0;
    for (auto i : ids) {
      for (; r < rights[i]; ++r) {
        bit.add(prev[c[r]] + 2, r + 2, 1);
        prev[c[r]] = r;
      }
      res[i] = bit.sum(lefts[i] + 1, lefts[i] + 2);
    }
    for (int i = 0; i < Q; ++i)
      cout << res[i] << endl;
  }
};

signed main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  std::istream &in(std::cin);
  std::ostream &out(std::cout);

  FRangeSetQuery solver;
  solver.solve(in, out);
  return 0;
}


Error: TLE

Fixed submission:

/**
 * code generated by JHelper
 * More info: https://github.com/AlexeyDmitriev/JHelper
 * @author tatsumack
 */

#include <fstream>
#include <iostream>

#include <bits/stdc++.h>

#define int long long
#define REP(i, n) for (int i = 0, i##_len = (n); i < i##_len; ++i)
#define FOR(i, a, b) for (int i = (a), i##_len = (b); i <= i##_len; ++i)
#define REV(i, a, b) for (int i = (a); i >= (b); --i)
#define CLR(a, b) memset((a), (b), sizeof(a))
#define DUMP(x) cout << #x << " = " << (x) << endl;
#define INF 1001001001001001001ll
#define fcout cout << fixed << setprecision(12)

using namespace std;

typedef pair<int, int> P;

vector<int> c;

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

    Mo(int n) : width((int)sqrt(n)), nl(0), nr(0), ptr(0), v(n) {}

    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];
      });
    }

    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);
    }

    map<int, int> cnt;
    int sum = 0;
    void add(int idx) {
      if (cnt[c[idx]] == 0)
        sum++;
      cnt[c[idx]]++;
    }

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

  void solve(std::istream &cin, std::ostream &cout) {
    int N, Q;
    cin >> N >> Q;
    c.resize(N);
    REP(i, N) cin >> c[i];

    Mo mo(N);
    REP(i, Q) {
      int l, r;
      cin >> l >> r;
      mo.insert(l - 1, r);
    }
    mo.build();

    vector<int> res(Q);
    REP(i, Q) {
      int idx = mo.process();
      res[idx] = mo.sum;
    }

    for (auto val : res)
      cout << val << endl;
  }
};

signed main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  std::istream &in(std::cin);
  std::ostream &out(std::cout);

  FRangeSetQuery solver;
  solver.solve(in, out);
  return 0;
}