Problem p02599 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
int maxi = 2e5 + 5, n;
vector<int> val(maxi), ano(maxi);
vector<vector<int>> node;

void init() {
  long long hei = ceil(log2(n));
  hei = 2 * pow(2, hei);
  node.clear();
  node.resize(hei);
  unordered_map<int, int> tmp;
  for (int i = n; i; i--) {
    if (tmp.find(val[i]) == tmp.end())
      ano[i] = n + 1;
    else
      ano[i] = tmp[val[i]];
    tmp[val[i]] = i;
  }
}
vector<int> merge(vector<int> &a, vector<int> &b) {
  vector<int> to_ret;
  int i = 0, j = 0;
  while (i < int(a.size()) && j < int(b.size()))
    if (a[i] < b[j])
      to_ret.emplace_back(a[i++]);
    else
      to_ret.emplace_back(b[j++]);
  while (i < int(a.size()))
    to_ret.emplace_back(a[i++]);
  while (j < int(b.size()))
    to_ret.emplace_back(b[j++]);
  return to_ret;
}

void build(int cur, int start, int end) {
  if (start == end) {
    node[cur].emplace_back(ano[start + 1]);
    return;
  }
  int mid = (start + end) / 2;
  build(2 * cur, start, mid);
  build(2 * cur + 1, mid + 1, end);
  node[cur] = merge(node[2 * cur], node[2 * cur + 1]);
}

int query(int cur, int l, int r, int rl, int rr, int k) {
  if (rr < l || r < rl)
    return 0;
  if (l >= rl && r <= rr)
    return node[cur].size() -
           (upper_bound(node[cur].begin(), node[cur].end(), k) -
            node[cur].begin());
  int mid = (l + r) / 2;
  return query(2 * cur, l, mid, rl, rr, k) +
         query(2 * cur + 1, mid + 1, r, rl, rr, k);
}

int solve2(int l, int r) {
  r = min(r, n);
  return query(1, 0, n - 1, l - 1, r - 1, r);
}

int main() {
  ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
  int l, r;
  int q;
  cin >> n >> q;
  for (int j = 1; j <= n; j++)
    cin >> val[j];
  init();
  build(1, 0, n - 1);
  while (q--) {
    cin >> l >> r;
    cout << solve2(l, r) << "\n";
  }
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
int maxi = 5e5 + 5, n;
vector<int> val(maxi), ano(maxi);
vector<vector<int>> node;

void init() {
  long long hei = ceil(log2(n));
  hei = 2 * pow(2, hei);
  node.clear();
  node.resize(hei);
  unordered_map<int, int> tmp;
  for (int i = n; i; i--) {
    if (tmp.find(val[i]) == tmp.end())
      ano[i] = n + 1;
    else
      ano[i] = tmp[val[i]];
    tmp[val[i]] = i;
  }
}
vector<int> merge(vector<int> &a, vector<int> &b) {
  vector<int> to_ret;
  int i = 0, j = 0;
  while (i < int(a.size()) && j < int(b.size()))
    if (a[i] < b[j])
      to_ret.emplace_back(a[i++]);
    else
      to_ret.emplace_back(b[j++]);
  while (i < int(a.size()))
    to_ret.emplace_back(a[i++]);
  while (j < int(b.size()))
    to_ret.emplace_back(b[j++]);
  return to_ret;
}

void build(int cur, int start, int end) {
  if (start == end) {
    node[cur].emplace_back(ano[start + 1]);
    return;
  }
  int mid = (start + end) / 2;
  build(2 * cur, start, mid);
  build(2 * cur + 1, mid + 1, end);
  node[cur] = merge(node[2 * cur], node[2 * cur + 1]);
}

int query(int cur, int l, int r, int rl, int rr, int k) {
  if (rr < l || r < rl)
    return 0;
  if (l >= rl && r <= rr)
    return node[cur].size() -
           (upper_bound(node[cur].begin(), node[cur].end(), k) -
            node[cur].begin());
  int mid = (l + r) / 2;
  return query(2 * cur, l, mid, rl, rr, k) +
         query(2 * cur + 1, mid + 1, r, rl, rr, k);
}

int solve2(int l, int r) {
  r = min(r, n);
  return query(1, 0, n - 1, l - 1, r - 1, r);
}

int main() {
  ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
  int l, r;
  int q;
  cin >> n >> q;
  for (int j = 1; j <= n; j++)
    cin >> val[j];
  init();
  build(1, 0, n - 1);
  while (q--) {
    cin >> l >> r;
    cout << solve2(l, r) << "\n";
  }
}