Problem p02599 (C++) — buggy submission, verdict: Runtime Error

#include <bits/stdc++.h>

using namespace std;
using int64 = long long;

constexpr int DEBUG = 0;

struct Query {
  int index;
  int l, r;
};

template <typename T> class SegmentTree {
private:
  function<T(T, T)> merge_fn;
  T empty_value;
  vector<T> nodes;
  int num_nodes;

  // Returns the fold of overwrap between [node_l, node_r) and [l, r).
  // nodes[node_index] needs to correspond to [node_l, node_r).
  T GetRangeInternal(int node_index, int node_l, int node_r, int l, int r) {
    if (node_r <= l || r <= node_l)
      return empty_value;
    if (l <= node_l && node_r <= r)
      return nodes[node_index];
    int node_m = (node_l + node_r) / 2;
    return merge_fn(GetRangeInternal(2 * node_index, node_l, node_m, l, r),
                    GetRangeInternal(2 * node_index + 1, node_m, node_r, l, r));
  }

public:
  // Arguments:
  // in_merge: The function to merge two values. It should be a monoid.
  // in_empty_value: The identity of the monoid.
  // xs: The initial values.
  SegmentTree(function<T(T, T)> merge_fn, T empty_value, const vector<T> &xs)
      : merge_fn(merge_fn), empty_value(empty_value) {
    int n = xs.size();
    num_nodes = 1;
    while (num_nodes < n)
      num_nodes *= 2;
    num_nodes *= 2;
    nodes = vector<T>(num_nodes, empty_value);
    for (int i = 0; i < xs.size(); ++i) {
      nodes[num_nodes / 2 + i] = xs[i];
    }
    for (int i = num_nodes / 2 - 1; i >= 1; i--) {
      nodes[i] = merge_fn(nodes[2 * i], nodes[2 * i + 1]);
    }
  }

  // Updates the i-th element to x.
  void Update(int i, T x) {
    nodes[num_nodes / 2 + i] = x;
    for (int cur = (num_nodes / 2 + i) / 2; cur > 0; cur /= 2) {
      nodes[cur] = merge_fn(nodes[2 * cur], nodes[2 * cur + 1]);
    }
  }

  // Returns the value of the range [l, r) merged by merge_fn.
  T GetRange(int l, int r) {
    return GetRangeInternal(1, 0, num_nodes / 2, l, r);
  }

  T Get(int i) { return nodes[num_nodes / 2 + i]; }
};

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);

  int n;
  int q;
  cin >> n >> q;
  vector<int> cs(n);
  for (int i = 0; i < n; i++) {
    cin >> cs[i];
    cs[i]--;
  }
  vector<vector<Query>> r_to_qs(n);
  for (int i = 0; i < q; i++) {
    int l, r;
    cin >> l >> r;
    l--;
    r--;
    r_to_qs[r].push_back({i, l, r});
  }

  vector<int> last_pos_vector(n, -1);

  SegmentTree<int64> tree([](int64 x, int64 y) { return x + y; }, 0,
                          vector<int64>(n, 0));

  vector<int64> ans(q);
  for (int r = 0; r < n; r++) {
    int c = cs[r];
    int p = last_pos_vector[c];
    last_pos_vector[c] = r;
    if (p >= 0) {
      tree.Update(p, tree.Get(p) - 1);
    }
    tree.Update(r, tree.Get(r) + 1);
    for (const auto &q : r_to_qs[r]) {
      int64 v = tree.GetRange(q.l, q.r + 1);
      ans[q.index] = v;
    }
  }
  for (int i = 0; i < q; i++) {
    cout << ans[i] << "\\n";
  }
}


Error: 0

Fixed submission:

#include <bits/stdc++.h>

using namespace std;
using int64 = long long;

constexpr int DEBUG = 0;

struct Query {
  int index;
  int l, r;
};

template <typename T> class SegmentTree {
private:
  function<T(T, T)> merge_fn;
  T empty_value;
  vector<T> nodes;
  int num_nodes;

  // Returns the fold of overwrap between [node_l, node_r) and [l, r).
  // nodes[node_index] needs to correspond to [node_l, node_r).
  T GetRangeInternal(int node_index, int node_l, int node_r, int l, int r) {
    if (node_r <= l || r <= node_l)
      return empty_value;
    if (l <= node_l && node_r <= r)
      return nodes[node_index];
    int node_m = (node_l + node_r) / 2;
    return merge_fn(GetRangeInternal(2 * node_index, node_l, node_m, l, r),
                    GetRangeInternal(2 * node_index + 1, node_m, node_r, l, r));
  }

public:
  // Arguments:
  // in_merge: The function to merge two values. It should be a monoid.
  // in_empty_value: The identity of the monoid.
  // xs: The initial values.
  SegmentTree(function<T(T, T)> merge_fn, T empty_value, const vector<T> &xs)
      : merge_fn(merge_fn), empty_value(empty_value) {
    int n = xs.size();
    num_nodes = 1;
    while (num_nodes < n)
      num_nodes *= 2;
    num_nodes *= 2;
    nodes = vector<T>(num_nodes, empty_value);
    for (int i = 0; i < xs.size(); ++i) {
      nodes[num_nodes / 2 + i] = xs[i];
    }
    for (int i = num_nodes / 2 - 1; i >= 1; i--) {
      nodes[i] = merge_fn(nodes[2 * i], nodes[2 * i + 1]);
    }
  }

  // Updates the i-th element to x.
  void Update(int i, T x) {
    nodes[num_nodes / 2 + i] = x;
    for (int cur = (num_nodes / 2 + i) / 2; cur > 0; cur /= 2) {
      nodes[cur] = merge_fn(nodes[2 * cur], nodes[2 * cur + 1]);
    }
  }

  // Returns the value of the range [l, r) merged by merge_fn.
  T GetRange(int l, int r) {
    return GetRangeInternal(1, 0, num_nodes / 2, l, r);
  }

  T Get(int i) { return nodes[num_nodes / 2 + i]; }
};

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);

  int n;
  int q;
  cin >> n >> q;
  vector<int> cs(n);
  for (int i = 0; i < n; i++) {
    cin >> cs[i];
    cs[i]--;
  }
  vector<vector<Query>> r_to_qs(n);
  for (int i = 0; i < q; i++) {
    int l, r;
    cin >> l >> r;
    l--;
    r--;
    r_to_qs[r].push_back({i, l, r});
  }

  vector<int> last_pos_vector(n, -1);

  SegmentTree<int64> tree([](int64 x, int64 y) { return x + y; }, 0,
                          vector<int64>(n, 0));

  vector<int64> ans(n);
  for (int r = 0; r < n; r++) {
    int c = cs[r];
    if (c >= 0) {
      int p = last_pos_vector[c];
      last_pos_vector[c] = r;
      if (p >= 0) {
        tree.Update(p, tree.Get(p) - 1);
      }
      tree.Update(r, tree.Get(r) + 1);
    }
    for (const auto &q : r_to_qs[r]) {
      int64 v = tree.GetRange(q.l, q.r + 1);
      ans[q.index] = v;
    }
  }
  for (int i = 0; i < q; i++) {
    cout << ans[i] << "\\n";
  }
}