Problem p02763 (C++)

Buggy submission (status: Runtime Error):
#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
#include <random>
using namespace std;
#define rep(i, a, n) for (int i = a; i < n; i++)
#define per(i, a, n) for (int i = n - 1; i >= a; i--)
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(), (x).end()
#define fi first
#define se second
#define sz(x) ((int)(x).size())
typedef vector<int> vi;
typedef long long ll;
typedef pair<int, int> pii;
typedef double db;
mt19937 mrand(random_device{}());
const ll mod = 1000000007;
int rnd(int x) { return mrand() % x; }
ll powmod(ll a, ll b) {
  ll res = 1;
  a %= mod;
  assert(b >= 0);
  for (; b; b >>= 1) {
    if (b & 1)
      res = res * a % mod;
    a = a * a % mod;
  }
  return res;
}
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
// head

int t;
const int MAXN = 500000 + 5;

int n;

struct Node {
  int lbit;
};

Node nodes[2 * MAXN - 1];

void init(int n_) {
  // 为了简单起见，将元素扩大到2的幂
  n = 1;
  while (n < n_)
    n *= 2;

  /*    for(int i=0;i<2*n-1;++i){*/
  // nodes[i].letters.clear();
  /*}*/
}

inline int getbit(char a) { return 1 << (a - 'a'); }
// 将第k个值更新为a
void update(int k, char a) {
  // 叶子节点
  k += n - 1;
  nodes[k].lbit = 0;
  nodes[k].lbit |= getbit(a);
  // 向上更新
  while (k > 0) {
    k = (k - 1) / 2;
    nodes[k].lbit = 0;
    auto &par = nodes[k].lbit;
    auto &chl = nodes[k * 2 + 1].lbit;
    auto &chr = nodes[k * 2 + 2].lbit;
    par = chl | chr;
  }
}

// 求[a,b)的最大prefix_max
// 后面的参数是为了计算方便传入的
// k是节点的编号，l,r表示这个节点代表区间[l,r)
// 外部调用时，使用query(a,b,0,0,n);

int query(int a, int b, int k, int l, int r) {
  // 如果[a,b)和[l,r)不相交，返回0
  if (r <= a || b <= l)
    return 0;
  // 如果[a,b)完全包含[l,r)，返回当前节点值
  if (a <= l && r <= b)
    return nodes[k].lbit;
  else {
    auto v1 = query(a, b, k * 2 + 1, l, (l + r) / 2);
    auto v2 = query(a, b, k * 2 + 2, (l + r) / 2, r);
    return v1 | v2;
  }
}

int main() {
  ios::sync_with_stdio(false);
#ifdef RG
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
#endif
  int nn;
  string s;
  cin >> nn;
  cin >> s;
  init(nn);
  rep(i, 0, nn) { update(i, s[i]); }
  int q;
  cin >> q;
  int l, r;
  char c;
  int ty;
  rep(i, 0, q) {
    cin >> ty;
    if (ty == 1) {
      cin >> l >> c;
      update(l - 1, c);
    } else {
      cin >> l >> r;
      auto ans = query(l - 1, r, 0, 0, n);
      int aaa = 0;
      for (int i = 0; i < 30; ++i) {
        if (ans & (1 << i))
          aaa++;
      }
      cout << aaa << endl;
    }
  }
  return 0;
}


Fixed submission:
#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
#include <random>
using namespace std;
#define rep(i, a, n) for (int i = a; i < n; i++)
#define per(i, a, n) for (int i = n - 1; i >= a; i--)
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(), (x).end()
#define fi first
#define se second
#define sz(x) ((int)(x).size())
typedef vector<int> vi;
typedef long long ll;
typedef pair<int, int> pii;
typedef double db;
mt19937 mrand(random_device{}());
const ll mod = 1000000007;
int rnd(int x) { return mrand() % x; }
ll powmod(ll a, ll b) {
  ll res = 1;
  a %= mod;
  assert(b >= 0);
  for (; b; b >>= 1) {
    if (b & 1)
      res = res * a % mod;
    a = a * a % mod;
  }
  return res;
}
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
// head

int t;
const int MAXN = 1000000 + 5;

int n;

struct Node {
  int lbit;
};

Node nodes[2 * MAXN - 1];

void init(int n_) {
  // 为了简单起见，将元素扩大到2的幂
  n = 1;
  while (n < n_)
    n *= 2;

  /*    for(int i=0;i<2*n-1;++i){*/
  // nodes[i].letters.clear();
  /*}*/
}

inline int getbit(char a) { return 1 << (a - 'a'); }
// 将第k个值更新为a
void update(int k, char a) {
  // 叶子节点
  k += n - 1;
  nodes[k].lbit = 0;
  nodes[k].lbit |= getbit(a);
  // 向上更新
  while (k > 0) {
    k = (k - 1) / 2;
    nodes[k].lbit = 0;
    auto &par = nodes[k].lbit;
    auto &chl = nodes[k * 2 + 1].lbit;
    auto &chr = nodes[k * 2 + 2].lbit;
    par = chl | chr;
  }
}

// 求[a,b)的最大prefix_max
// 后面的参数是为了计算方便传入的
// k是节点的编号，l,r表示这个节点代表区间[l,r)
// 外部调用时，使用query(a,b,0,0,n);

int query(int a, int b, int k, int l, int r) {
  // 如果[a,b)和[l,r)不相交，返回0
  if (r <= a || b <= l)
    return 0;
  // 如果[a,b)完全包含[l,r)，返回当前节点值
  if (a <= l && r <= b)
    return nodes[k].lbit;
  else {
    auto v1 = query(a, b, k * 2 + 1, l, (l + r) / 2);
    auto v2 = query(a, b, k * 2 + 2, (l + r) / 2, r);
    return v1 | v2;
  }
}

int main() {
  ios::sync_with_stdio(false);
#ifdef RG
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
#endif
  int nn;
  string s;
  cin >> nn;
  cin >> s;
  init(nn);
  rep(i, 0, nn) { update(i, s[i]); }
  int q;
  cin >> q;
  int l, r;
  char c;
  int ty;
  rep(i, 0, q) {
    cin >> ty;
    if (ty == 1) {
      cin >> l >> c;
      update(l - 1, c);
    } else {
      cin >> l >> r;
      auto ans = query(l - 1, r, 0, 0, n);
      int aaa = 0;
      for (int i = 0; i < 30; ++i) {
        if (ans & (1 << i))
          aaa++;
      }
      cout << aaa << endl;
    }
  }
  return 0;
}