Problem p02763 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
#define REP(i, n) for (int i = 0; i < (int)(n); i++)
template <typename Monoid = ll> class SegmentTree {
public:
  using Monoid_func = function<Monoid(Monoid, Monoid)>;
  ll size;
  std::vector<Monoid> segment; // 1-indexed 葉ノードは size ~ 2*size-1
  Monoid Monoid_unit;
  Monoid_func Monoid_calc;

  SegmentTree(
      ll N, Monoid Monoid_unit = 0,
      Monoid_func Monoid_calc = [](ll a, ll b) { return a + b; })
      : size(1), Monoid_unit(Monoid_unit), Monoid_calc(Monoid_calc) {
    while (size < N)
      size <<= 1;
    segment.assign(size * 2, Monoid_unit);
  }

  void set(ll k, Monoid a) { segment[k + size] = a; }
  void build() { // 全てのノードを再計算
    for (ll k = size - 1; k > 0; k--)
      segment[k] = Monoid_calc(segment[k * 2], segment[k * 2 + 1]);
  }
  void build(std::vector<Monoid> v) {
    for (ll k = 0; k < size; k++) {
      segment[k + size] = v[k];
    }
    build();
  }
  void update_replace(ll k, Monoid a) {
    k += size;
    segment[k] = a;
    while (k >>= 1)
      segment[k] = Monoid_calc(segment[k * 2], segment[k * 2 + 1]);
  }
  void update_add(ll k, Monoid a) {
    k += size;
    segment[k] = Monoid_calc(segment[k], a);
    while (k >>= 1)
      segment[k] = Monoid_calc(segment[k * 2], segment[k * 2 + 1]);
  }
  void update_del(ll k, Monoid a) {
    k += size;
    segment[k] = Monoid_calc_back(segment[k], a);
    while (k >>= 1)
      segment[k] = Monoid_calc_back(segment[k * 2], segment[k * 2 + 1]);
  }
  Monoid query(ll a, ll b) { // [a, b)の演算結果
    Monoid l = Monoid_unit, r = Monoid_unit;
    for (a += size, b += size; a < b; a >>= 1, b >>= 1) {
      if (a % 2 == 1)
        l = Monoid_calc(l, segment[a++]);
      if (b % 2 == 1)
        r = Monoid_calc(segment[--b], r);
    }
    return Monoid_calc(l, r);
  }

  Monoid operator[](const ll &k) const { return segment[k + size]; }
};

int main() {
  ll n, q;
  cin >> n;
  string s;
  cin >> s;
  vector<int> beg(26);
  vector<vector<int>> in;
  in.clear();
  for (auto i : s) {
    vector<int> v(26);
    v[i - 'a'] = 1;
    in.push_back(v);
  }
  while (in.size() < 26)
    in.push_back(beg);
  SegmentTree<vector<int>> st(n, beg, [](vector<int> a, vector<int> b) {
    vector<int> ans(26);
    REP(i, 26) ans[i] = a[i] + b[i];
    return ans;
  });
  st.build(in);
  ll num, l, r;
  char c;
  cin >> q;
  REP(i, q) {
    cin >> num;
    if (num == 1) {
      cin >> l >> c;
      vector<int> v(26);
      v[c - 'a']++;
      vector<int> vv = st[l - 1];
      int vvv;
      REP(j, 26) if (vv[j] != 0) vvv = j;
      v[vvv]--;
      st.update_add(l - 1, v);
    } else {
      cin >> l >> r;
      vector<int> ans = st.query(l - 1, r);
      ll out = 0;
      REP(i, 26) out += (ans[i] != 0);
      cout << out << endl;
    }
  }
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
#define REP(i, n) for (int i = 0; i < (int)(n); i++)
template <typename Monoid = ll> class SegmentTree {
public:
  using Monoid_func = function<Monoid(Monoid, Monoid)>;
  ll size;
  std::vector<Monoid> segment; // 1-indexed 葉ノードは size ~ 2*size-1
  Monoid Monoid_unit;
  Monoid_func Monoid_calc;

  SegmentTree(
      ll N, Monoid Monoid_unit = 0,
      Monoid_func Monoid_calc = [](ll a, ll b) { return a + b; })
      : size(1), Monoid_unit(Monoid_unit), Monoid_calc(Monoid_calc) {
    while (size < N)
      size <<= 1;
    segment.assign(size * 2, Monoid_unit);
  }

  void set(ll k, Monoid a) { segment[k + size] = a; }
  void build() { // 全てのノードを再計算
    for (ll k = size - 1; k > 0; k--)
      segment[k] = Monoid_calc(segment[k * 2], segment[k * 2 + 1]);
  }
  void build(std::vector<Monoid> v) {
    for (ll k = 0; k < size; k++) {
      segment[k + size] = v[k];
    }
    build();
  }
  void update_replace(ll k, Monoid a) {
    k += size;
    segment[k] = a;
    while (k >>= 1)
      segment[k] = Monoid_calc(segment[k * 2], segment[k * 2 + 1]);
  }
  void update_add(ll k, Monoid a) {
    k += size;
    segment[k] = Monoid_calc(segment[k], a);
    while (k >>= 1)
      segment[k] = Monoid_calc(segment[k * 2], segment[k * 2 + 1]);
  }
  void update_del(ll k, Monoid a) {
    k += size;
    segment[k] = Monoid_calc_back(segment[k], a);
    while (k >>= 1)
      segment[k] = Monoid_calc_back(segment[k * 2], segment[k * 2 + 1]);
  }
  Monoid query(ll a, ll b) { // [a, b)の演算結果
    Monoid l = Monoid_unit, r = Monoid_unit;
    for (a += size, b += size; a < b; a >>= 1, b >>= 1) {
      if (a % 2 == 1)
        l = Monoid_calc(l, segment[a++]);
      if (b % 2 == 1)
        r = Monoid_calc(segment[--b], r);
    }
    return Monoid_calc(l, r);
  }

  Monoid operator[](const ll &k) const { return segment[k + size]; }
};

int main() {
  ll n, q;
  cin >> n;
  string s;
  cin >> s;
  vector<int> beg(26);
  vector<vector<int>> in;
  in.clear();
  for (auto i : s) {
    vector<int> v(26);
    v[i - 'a'] = 1;
    in.push_back(v);
  }
  int size = 1;
  while (size < n)
    size <<= 1;
  while (in.size() < size)
    in.push_back(beg);
  SegmentTree<vector<int>> st(n, beg, [](vector<int> a, vector<int> b) {
    vector<int> ans(26);
    REP(i, 26) ans[i] = a[i] + b[i];
    return ans;
  });
  st.build(in);
  ll num, l, r;
  char c;
  cin >> q;
  REP(i, q) {
    cin >> num;
    if (num == 1) {
      cin >> l >> c;
      vector<int> v(26);
      v[c - 'a']++;
      vector<int> vv = st[l - 1];
      int vvv;
      REP(j, 26) if (vv[j] != 0) vvv = j;
      v[vvv]--;
      st.update_add(l - 1, v);
    } else {
      cin >> l >> r;
      vector<int> ans = st.query(l - 1, r);
      ll out = 0;
      REP(i, 26) out += (ans[i] != 0);
      cout << out << endl;
    }
  }
  return 0;
}