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

#include <algorithm>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;
#define rep(i, n) for (int(i) = 0; (i) < (n); (i)++)
#define FOR(i, m, n) for (int(i) = (m); (i) < (n); (i)++)
#define All(v) (v).begin(), (v).end()
#define pb push_back
#define MP(a, b) make_pair((a), (b))
using ll = long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
const int INF = 1 << 30;
const ll LINF = 1LL << 60;
const int MOD = 1e9 + 7;

// 参考：https://qiita.com/drken/items/1b7e6e459c24a83bb7fd
// 1-indexed BIT
// add:log(N),sum:log(N),get_k-th:log(N)
// https://codeforces.com/contest/1354/problem/D
struct BIT {
  vector<ll> dat;

  BIT(int n) {
    dat.resize(n + 1);
    for (int i = 0; i < (int)dat.size(); i++)
      dat[i] = 0;
  }

  // a is 1-indexed
  void add(int a, ll x) {
    for (int i = a; i < (int)dat.size(); i += i & -i)
      dat[i] = dat[i] + x;
  }

  // [1,a], a is 1-indexed
  ll sum(int a) {
    ll res = 0;
    for (int i = a; i > 0; i -= i & -i) {
      res = res + dat[i];
    }
    return res;
  }

  // [a,b), a and b are 1-indexed
  ll sum(int a, int b) { return sum(b - 1) - sum(a - 1); }

  // k-th number (k is 1-indexed)
  // lower_bound
  int get(ll k) {
    if (k <= 0)
      return 0;
    int res = 0;
    int N = 1;
    while (N < (int)dat.size())
      N *= 2;
    for (int i = N / 2; i > 0; i /= 2) {
      if (res + i < (int)dat.size() && dat[res + i] < k) {
        k = k - dat[res + i];
        res = res + i;
      }
    }
    return res + 1;
  }
};

int main() {
  int N, Q;
  cin >> N >> Q;
  vector<int> C(N);
  rep(i, N) cin >> C[i];
  vector<int> last(N + 1, -1);
  vector<pair<pii, int>> query(Q);
  rep(i, Q) {
    int l, r;
    cin >> l >> r;
    query[i] = MP(MP(r, l), i);
  }
  vector<int> res(Q);
  sort(All(query));
  int lastr = query[0].first.first;
  BIT bit(N + 1);
  rep(i, lastr) { last[C[i]] = i + 1; }
  rep(i, N + 1) {
    if (last[i] != -1)
      bit.add(last[i], 1);
  }
  rep(i, Q) {
    for (int j = lastr + 1; j <= query[i].first.first; j++) {
      int tmp = last[C[j - 1]];
      last[C[j - 1]] = j;
      if (tmp > 0)
        bit.add(tmp, -1);
      bit.add(j, 1);
      lastr = query[i].first.first;
    }
    res[query[i].second] =
        bit.sum(query[i].first.second, query[i].first.first + 1);
  }
  rep(i, Q) { cout << res[i] << endl; }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;
#define rep(i, n) for (int(i) = 0; (i) < (n); (i)++)
#define FOR(i, m, n) for (int(i) = (m); (i) < (n); (i)++)
#define All(v) (v).begin(), (v).end()
#define pb push_back
#define MP(a, b) make_pair((a), (b))
using ll = long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
const int INF = 1 << 30;
const ll LINF = 1LL << 60;
const int MOD = 1e9 + 7;

// 参考：https://qiita.com/drken/items/1b7e6e459c24a83bb7fd
// 1-indexed BIT
// add:log(N),sum:log(N),get_k-th:log(N)
// https://codeforces.com/contest/1354/problem/D
struct BIT {
  vector<ll> dat;

  BIT(int n) {
    dat.resize(n + 1);
    for (int i = 0; i < (int)dat.size(); i++)
      dat[i] = 0;
  }

  // a is 1-indexed
  void add(int a, ll x) {
    for (int i = a; i < (int)dat.size(); i += i & -i)
      dat[i] = dat[i] + x;
  }

  // [1,a], a is 1-indexed
  ll sum(int a) {
    ll res = 0;
    for (int i = a; i > 0; i -= i & -i) {
      res = res + dat[i];
    }
    return res;
  }

  // [a,b), a and b are 1-indexed
  ll sum(int a, int b) { return sum(b - 1) - sum(a - 1); }

  // k-th number (k is 1-indexed)
  // lower_bound
  int get(ll k) {
    if (k <= 0)
      return 0;
    int res = 0;
    int N = 1;
    while (N < (int)dat.size())
      N *= 2;
    for (int i = N / 2; i > 0; i /= 2) {
      if (res + i < (int)dat.size() && dat[res + i] < k) {
        k = k - dat[res + i];
        res = res + i;
      }
    }
    return res + 1;
  }
};

int main() {
  int N, Q;
  cin >> N >> Q;
  vector<int> C(N);
  rep(i, N) cin >> C[i];
  vector<int> last(N + 1, -1);
  vector<pair<pii, int>> query(Q);
  rep(i, Q) {
    int l, r;
    cin >> l >> r;
    query[i] = MP(MP(r, l), i);
  }
  vector<int> res(Q);
  sort(All(query));
  int lastr = query[0].first.first;
  BIT bit(N + 1);
  rep(i, lastr) { last[C[i]] = i + 1; }
  rep(i, N + 1) {
    if (last[i] != -1)
      bit.add(last[i], 1);
  }
  rep(i, Q) {
    for (int j = lastr + 1; j <= query[i].first.first; j++) {
      int tmp = last[C[j - 1]];
      last[C[j - 1]] = j;
      if (tmp > 0)
        bit.add(tmp, -1);
      bit.add(j, 1);
    }
    res[query[i].second] =
        bit.sum(query[i].first.second, query[i].first.first + 1);
  }
  rep(i, Q) { cout << res[i] << endl; }
  return 0;
}