Problem p02599 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <climits>
#include <cmath>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;
int c[500000];
int sqrtN = 710;
struct SqrtDecomposition {
  int N, K;
  vector<long long> data;
  vector<long long> bucketSum;

  SqrtDecomposition(int n) {
    N = n;
    K = (N + sqrtN - 1) / sqrtN;
    data.assign(N, 0);
    bucketSum.assign(K, 0);
  }

  void add(int x, int y) {
    data[x] += y;
    bucketSum[x / sqrtN] += y;
  }

  long long getSum(int x, int y) {
    long long ans = 0;
    if (y - x < sqrtN) {
      for (int i = x; i < y; i++) {
        ans += data[i];
      }
      return ans;
    }
    for (int i = x / sqrtN + 1; i < y / sqrtN; i++) {
      ans += bucketSum[i];
    }

    for (int i = x; i < (x / sqrtN + 1) * sqrtN; i++) {
      ans += data[i];
    }
    for (int i = y / sqrtN * sqrtN; i < y; i++) {
      ans += data[i];
    }
    return ans;
  }
};

int ans[500000];
int last_appeared[500001];
pair<pair<int, int>, int> RL_ind[500000];
int main() {
  int N;
  int Q;
  cin >> N >> Q;

  int max_c = 0;
  for (int i = 0; i < N; i++) {
    cin >> c[i];
    max_c = max(max_c, c[i]);
  }

  for (int i = 0; i < Q; i++) {
    int l;
    int r;
    cin >> l >> r;
    RL_ind[i] = make_pair(make_pair(r, l), i);
  }
  for (int i = 0; i <= max_c; i++) {
    last_appeared[i] = -1;
  }

  sort(RL_ind, RL_ind + Q);

  SqrtDecomposition sq(N);
  int last_R = 0;
  for (int i = 0; i < Q; i++) {
    int cur_L = RL_ind[i].first.second;
    int cur_R = RL_ind[i].first.first;
    int ans_ind = RL_ind[i].second;
    for (int j = last_R; j < cur_R; j++) {
      if (last_appeared[c[j]] >= 0) {
        sq.add(last_appeared[c[j]], -1);
      }
      last_appeared[c[j]] = j;
      sq.add(j, 1);
    }
    ans[ans_ind] = sq.getSum(cur_L - 1, cur_R);
  }

  for (int i = 0; i < Q; i++) {
    cout << ans[i] << endl;
  }

  return 0;
}


Fixed submission:
#include <algorithm>
#include <climits>
#include <cmath>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;
int c[500000];
int sqrtN = 710;
struct SqrtDecomposition {
  int N, K;
  vector<long long> data;
  vector<long long> bucketSum;

  SqrtDecomposition(int n) {
    N = n;
    K = (N + sqrtN - 1) / sqrtN;
    data.assign(N, 0);
    bucketSum.assign(K, 0);
  }

  void add(int x, int y) {
    data[x] += y;
    bucketSum[x / sqrtN] += y;
  }

  long long getSum(int x, int y) {
    long long ans = 0;
    if (y - x < sqrtN) {
      for (int i = x; i < y; i++) {
        ans += data[i];
      }
      return ans;
    }
    for (int i = x / sqrtN + 1; i < y / sqrtN; i++) {
      ans += bucketSum[i];
    }

    for (int i = x; i < (x / sqrtN + 1) * sqrtN; i++) {
      ans += data[i];
    }
    for (int i = y / sqrtN * sqrtN; i < y; i++) {
      ans += data[i];
    }
    return ans;
  }
};

int ans[500000];
int last_appeared[500001];
pair<pair<int, int>, int> RL_ind[500000];
int main() {
  int N;
  int Q;
  cin >> N >> Q;

  int max_c = 0;
  for (int i = 0; i < N; i++) {
    cin >> c[i];
    max_c = max(max_c, c[i]);
  }

  for (int i = 0; i < Q; i++) {
    int l;
    int r;
    cin >> l >> r;
    RL_ind[i] = make_pair(make_pair(r, l), i);
  }
  for (int i = 0; i <= max_c; i++) {
    last_appeared[i] = -1;
  }

  sort(RL_ind, RL_ind + Q);

  SqrtDecomposition sq(N);
  int last_R = 0;
  for (int i = 0; i < Q; i++) {
    int cur_L = RL_ind[i].first.second;
    int cur_R = RL_ind[i].first.first;
    int ans_ind = RL_ind[i].second;
    for (int j = last_R; j < cur_R; j++) {
      if (last_appeared[c[j]] >= 0) {
        sq.add(last_appeared[c[j]], -1);
      }
      last_appeared[c[j]] = j;
      sq.add(j, 1);
    }
    ans[ans_ind] = sq.getSum(cur_L - 1, cur_R);
    last_R = cur_R;
  }

  for (int i = 0; i < Q; i++) {
    cout << ans[i] << endl;
  }

  return 0;
}