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

#include <bits/stdc++.h>
using namespace std;
using lint = long long;
constexpr lint inf = 1LL << 60;
constexpr lint mod = 1000000007;

// 0-indexed bottom up Segment Tree
// UNIT is the identity element of operation func
template <typename T = int> struct SegmentTree {
  using F = function<T(T, T)>;
  int n;
  vector<T> dat;
  F func;
  T UNIT;

  SegmentTree(int n_, F func_, T UNIT_) : func(func_), UNIT(UNIT_) {
    n = 1;
    // full binary tree: num of leaves = n = 2^k >= n_
    while (n < n_)
      n *= 2;
    dat.assign(2 * n - 1, UNIT);
  }
  SegmentTree(vector<T> v_, F func_, T UNIT_) : func(func_), UNIT(UNIT_) {
    n = 1;
    int nv = v_.size();
    while (n < nv)
      n *= 2;
    dat.assign(2 * n - 1, UNIT);
    for (int i = 0; i < nv; ++i) {
      dat[n - 1 + i] = v_[i];
    }
    for (int i = n - 2; i >= 0; --i) {
      dat[i] = func(dat[2 * i + 1], dat[2 * i + 2]);
    }
  }
  void update(int k, T a) {
    // leaves are at index n-1 to 2*n-2
    k += n - 1;
    dat[k] = a;
    while (k > 0) {
      // k -> parent node
      k = (k - 1) / 2;
      // func(child nodes)
      dat[k] = func(dat[2 * k + 1], dat[2 * k + 2]);
    }
  }
  // get result of func() in [l, r)
  T query(int l, int r) {
    l += n - 1;
    r += n - 1;
    T retl = UNIT, retr = UNIT;
    while (l < r) {
      if ((l & 1) == 0)
        retl = func(retl, dat[l]);
      if ((r & 1) == 0)
        retr = func(dat[r - 1], retr);
      l = l / 2;
      r = (r - 1) / 2;
    }
    return func(retl, retr);
  }
};

int main() {
  cin.tie(nullptr);
  ios::sync_with_stdio(false);
  int n, q;
  cin >> n >> q;
  vector<int> c(n);
  for (int i = 0; i < n; ++i) {
    cin >> c[i];
    c[i]--;
  }
  vector<pair<pair<int, int>, int>> rl;
  for (int i = 0; i < q; ++i) {
    int l, r;
    cin >> l >> r;
    l--, r--;
    rl.push_back({{r, l}, i});
  }
  sort(rl.begin(), rl.end());
  vector<int> last(n, -1);
  auto f = [](lint l, lint r) { return l + r; };
  const lint unit = 0;
  SegmentTree<lint> seg(n + 1, f, unit);
  int cr = -1;
  vector<int> ret(q);
  for (int i = 0; i < q; ++i) {
    while (cr < rl[i].first.first) {
      cr++;
      if (last[c[cr]] != -1)
        seg.update(last[c[cr]], 0);
      last[c[cr]] = cr;
      seg.update(last[c[cr]], 1);
    }
    ret[rl[i].second] = seg.query(rl[i].first.second, rl[i].first.first + 1);
  }
  for (auto &r : ret) {
    cout << r << "\\n";
  }
  return 0;
}

Error: 0

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
using lint = long long;
constexpr lint inf = 1LL << 60;
constexpr lint mod = 1000000007;

// 0-indexed bottom up Segment Tree
// UNIT is the identity element of operation func
template <typename T = int> struct SegmentTree {
  using F = function<T(T, T)>;
  int n;
  vector<T> dat;
  F func;
  T UNIT;

  SegmentTree(int n_, F func_, T UNIT_) : func(func_), UNIT(UNIT_) {
    n = 1;
    // full binary tree: num of leaves = n = 2^k >= n_
    while (n < n_)
      n *= 2;
    dat.assign(2 * n - 1, UNIT);
  }
  SegmentTree(vector<T> v_, F func_, T UNIT_) : func(func_), UNIT(UNIT_) {
    n = 1;
    int nv = v_.size();
    while (n < nv)
      n *= 2;
    dat.assign(2 * n - 1, UNIT);
    for (int i = 0; i < nv; ++i) {
      dat[n - 1 + i] = v_[i];
    }
    for (int i = n - 2; i >= 0; --i) {
      dat[i] = func(dat[2 * i + 1], dat[2 * i + 2]);
    }
  }
  void update(int k, T a) {
    // leaves are at index n-1 to 2*n-2
    k += n - 1;
    dat[k] = a;
    while (k > 0) {
      // k -> parent node
      k = (k - 1) / 2;
      // func(child nodes)
      dat[k] = func(dat[2 * k + 1], dat[2 * k + 2]);
    }
  }
  // get result of func() in [l, r)
  T query(int l, int r) {
    l += n - 1;
    r += n - 1;
    T retl = UNIT, retr = UNIT;
    while (l < r) {
      if ((l & 1) == 0)
        retl = func(retl, dat[l]);
      if ((r & 1) == 0)
        retr = func(dat[r - 1], retr);
      l = l / 2;
      r = (r - 1) / 2;
    }
    return func(retl, retr);
  }
};

int main() {
  cin.tie(nullptr);
  ios::sync_with_stdio(false);
  int n, q;
  cin >> n >> q;
  vector<int> c(n);
  for (int i = 0; i < n; ++i) {
    cin >> c[i];
  }
  vector<pair<pair<int, int>, int>> rl;
  for (int i = 0; i < q; ++i) {
    int l, r;
    cin >> l >> r;
    l--, r--;
    rl.push_back({{r, l}, i});
  }
  sort(rl.begin(), rl.end());
  vector<int> last(n, -1);
  auto f = [](lint l, lint r) { return l + r; };
  const lint unit = 0;
  SegmentTree<lint> seg(n, f, unit);
  int cr = -1;
  vector<int> ret(q);
  for (int i = 0; i < q; ++i) {
    while (cr < rl[i].first.first) {
      cr++;
      if (last[c[cr]] != -1)
        seg.update(last[c[cr]], 0);
      last[c[cr]] = cr;
      seg.update(last[c[cr]], 1);
    }
    ret[rl[i].second] = seg.query(rl[i].first.second, rl[i].first.first + 1);
  }
  for (auto &r : ret) {
    cout << r << "\\n";
  }
  return 0;
}