Problem p02763 (C++)

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

template <typename T> void print(T t) { cout << t << endl; }
template <typename T, typename... Args> void print(T t, Args... args) {
  cout << t << " ";
  print(args...);
}

#define IOS                                                                    \
  ios::sync_with_stdio(0);                                                     \
  cin.tie(0);                                                                  \
  cout.tie(0);
#define endl '\n'
#define int long long
#define double long double

int n;
string s;
int tree[1000005];
void build(int i, int l, int r) {
  if (l == r) {
    tree[i] = (1ll << (s[l - 1] - 'a'));
    return;
  }
  int mid = (l + r) / 2;
  build(i * 2, l, mid);
  build(i * 2 + 1, mid + 1, r);
  tree[i] = tree[i * 2] | tree[i * 2 + 1];
}
void update(int i, int l, int r, int l1, int r1, int val) {
  if (l1 > r1 || l > r1 || l1 > r)
    return;
  if (l1 <= l && r <= r1) {
    tree[i] = (1ll << val);
    return;
  }
  int mid = (l + r) / 2;
  update(i * 2, l, mid, l1, r1, val);
  update(i * 2 + 1, mid + 1, r, l1, r1, val);
  tree[i] = tree[i * 2] | tree[i * 2 + 1];
}
int query(int i, int l, int r, int l1, int r1) {
  if (l1 > r1 || l > r1 || l1 > r)
    return 0;
  if (l1 <= l && r <= r1)
    return tree[i];
  int mid = (l + r) / 2;
  return query(i * 2, l, mid, l1, r1) | query(i * 2 + 1, mid + 1, r, l1, r1);
}
int32_t main() {
  IOS;
  cin >> n >> s;
  build(1, 1, n);
  int q;
  cin >> q;
  while (q--) {
    int type;
    cin >> type;
    if (type == 2) {
      int a, b;
      cin >> a >> b;
      print(__builtin_popcount(query(1, 1, n, a, b)));
    } else {
      int pos;
      char type;
      cin >> pos >> type;
      update(1, 1, n, pos, pos, type - 'a');
    }
  }
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;

template <typename T> void print(T t) { cout << t << endl; }
template <typename T, typename... Args> void print(T t, Args... args) {
  cout << t << " ";
  print(args...);
}

#define IOS                                                                    \
  ios::sync_with_stdio(0);                                                     \
  cin.tie(0);                                                                  \
  cout.tie(0);
#define endl '\n'
#define int long long
#define double long double

int n;
string s;
int tree[2000005];
void build(int i, int l, int r) {
  if (l == r) {
    tree[i] = (1ll << (s[l - 1] - 'a'));
    return;
  }
  int mid = (l + r) / 2;
  build(i * 2, l, mid);
  build(i * 2 + 1, mid + 1, r);
  tree[i] = tree[i * 2] | tree[i * 2 + 1];
}
void update(int i, int l, int r, int l1, int r1, int val) {
  if (l1 > r1 || l > r1 || l1 > r)
    return;
  if (l1 <= l && r <= r1) {
    tree[i] = (1ll << val);
    return;
  }
  int mid = (l + r) / 2;
  update(i * 2, l, mid, l1, r1, val);
  update(i * 2 + 1, mid + 1, r, l1, r1, val);
  tree[i] = tree[i * 2] | tree[i * 2 + 1];
}
int query(int i, int l, int r, int l1, int r1) {
  if (l1 > r1 || l > r1 || l1 > r)
    return 0;
  if (l1 <= l && r <= r1)
    return tree[i];
  int mid = (l + r) / 2;
  return query(i * 2, l, mid, l1, r1) | query(i * 2 + 1, mid + 1, r, l1, r1);
}
int32_t main() {
  IOS;
  cin >> n >> s;
  build(1, 1, n);
  int q;
  cin >> q;
  while (q--) {
    int type;
    cin >> type;
    if (type == 2) {
      int a, b;
      cin >> a >> b;
      print(__builtin_popcount(query(1, 1, n, a, b)));
    } else {
      int pos;
      char type;
      cin >> pos >> type;
      update(1, 1, n, pos, pos, type - 'a');
    }
  }
}