Problem p02763 (C++)

Buggy submission (status: Runtime Error):
#define fast ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#include <bits/stdc++.h>
#define pll pair<ll, ll>
#define vi vector<int>
#define ld long double
#define ll long long
#define pb push_back
#define mid (l + r) / 2
#define S second
#define F first
using namespace std;
int n, q;
string s;
vi tree[500009];
void build(int node, int l, int r) {
  if (l == r) {
    for (int i = 0; i < 26; i++)
      tree[node].pb(0);
    tree[node][s[l] - 'a'] = 1;
    return;
  }
  build(node * 2, l, mid);
  build(node * 2 + 1, mid + 1, r);
  for (int i = 0; i < 26; i++) {
    tree[node].pb(0);
    tree[node][i] = tree[node * 2][i];
    tree[node][i] += tree[node * 2 + 1][i];
  }
}
void upd(int node, int l, int r, int k, char z) {
  if (l == r) {
    tree[node][s[l] - 'a'] = 0;
    s[l] = z;
    tree[node][s[l] - 'a'] = 1;
    return;
  }
  if (k <= mid)
    upd(node * 2, l, mid, k, z);
  else
    upd(node * 2 + 1, mid + 1, r, k, z);
  for (int i = 0; i < 26; i++) {
    tree[node][i] = tree[node * 2][i];
    tree[node][i] += tree[node * 2 + 1][i];
  }
}
vi query(int node, int l, int r, int s, int e) {
  if (s <= l && e >= r)
    return tree[node];
  if (s <= mid && e > mid) {
    vi a = query(node * 2, l, mid, s, e);
    vi b = query(node * 2 + 1, mid + 1, r, s, e);
    vi ret;
    for (int i = 0; i < 26; i++) {
      ret.pb(0);
      ret[i] = a[i] + b[i];
    }
    return ret;
  }
  if (s <= mid)
    return query(node * 2, l, mid, s, e);
  return query(node * 2 + 1, mid + 1, r, s, e);
}
int main() {
  fast, cin >> n >> s >> q;
  build(1, 0, n - 1);
  while (q--) {
    int t;
    cin >> t;
    if (t == 1) {
      int id;
      char z;
      cin >> id >> z, id--;
      upd(1, 0, n - 1, id, z);
    } else {
      int l, r;
      cin >> l >> r;
      l--;
      r--;
      vi v = query(1, 0, n - 1, l, r);
      int curr = 0;
      for (int i = 0; i < 26; i++) {
        curr += (v[i] > 0);
      }
      cout << curr << endl;
    }
  }
}


Fixed submission:
#define fast ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#include <bits/stdc++.h>
#define pll pair<ll, ll>
#define vi vector<int>
#define ld long double
#define ll long long
#define pb push_back
#define mid (l + r) / 2
#define S second
#define F first
using namespace std;
int n, q;
string s;
vi tree[2000009];
void build(int node, int l, int r) {
  if (l == r) {
    for (int i = 0; i < 26; i++)
      tree[node].pb(0);
    tree[node][s[l] - 'a'] = 1;
    return;
  }
  build(node * 2, l, mid);
  build(node * 2 + 1, mid + 1, r);
  for (int i = 0; i < 26; i++) {
    tree[node].pb(0);
    tree[node][i] = tree[node * 2][i];
    tree[node][i] += tree[node * 2 + 1][i];
  }
}
void upd(int node, int l, int r, int k, char z) {
  if (l == r) {
    tree[node][s[l] - 'a'] = 0;
    s[l] = z;
    tree[node][s[l] - 'a'] = 1;
    return;
  }
  if (k <= mid)
    upd(node * 2, l, mid, k, z);
  else
    upd(node * 2 + 1, mid + 1, r, k, z);
  for (int i = 0; i < 26; i++) {
    tree[node][i] = tree[node * 2][i];
    tree[node][i] += tree[node * 2 + 1][i];
  }
}
vi query(int node, int l, int r, int s, int e) {
  if (s <= l && e >= r)
    return tree[node];
  if (s <= mid && e > mid) {
    vi a = query(node * 2, l, mid, s, e);
    vi b = query(node * 2 + 1, mid + 1, r, s, e);
    vi ret;
    for (int i = 0; i < 26; i++) {
      ret.pb(0);
      ret[i] = a[i] + b[i];
    }
    return ret;
  }
  if (s <= mid)
    return query(node * 2, l, mid, s, e);
  return query(node * 2 + 1, mid + 1, r, s, e);
}
int main() {
  fast, cin >> n >> s >> q;
  build(1, 0, n - 1);
  while (q--) {
    int t;
    cin >> t;
    if (t == 1) {
      int id;
      char z;
      cin >> id >> z, id--;
      upd(1, 0, n - 1, id, z);
    } else {
      int l, r;
      cin >> l >> r;
      l--;
      r--;
      vi v = query(1, 0, n - 1, l, r);
      int curr = 0;
      for (int i = 0; i < 26; i++) {
        curr += (v[i] > 0);
      }
      cout << curr << endl;
    }
  }
}