Problem p02763 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <iostream>
#include <map>
#include <set>
#include <string>
#include <utility>
#include <vector>
typedef long long ll;
#define rep(i, n) for (int i = 0; i < n; i++)
using namespace std;
ll intpow(int n, int m) {
  if (m == 0)
    return 1;
  return n * intpow(n, m - 1);
}
ll gcd(ll n, ll m) {
  n = max(n, m);
  m = min(n, m);
  if (n % m == 0)
    return m;
  return gcd(m, n % m);
}
ll lcm(ll n, ll m) { return n * m / gcd(n, m); }
const int inf = 2147483647;
int n;
bool node[1000000][26];
void init(int n_) {
  while (n < n_)
    n *= 2;
  rep(i, 2 * n - 1) { rep(j, 26) node[i][j] = 0; }
}
void update(int i, char a, char b) {
  i += n - 1;
  int m1 = a - 97;
  int m2 = b - 97;
  node[i][m1] = 0;
  node[i][m2] = 1;
  while (i > 0) {
    i = (i - 1) / 2;
    node[i][m1] = node[i * 2 + 1][m1] || node[i * 2 + 2][m1];
    node[i][m2] = node[i * 2 + 1][m2] || node[i * 2 + 2][m2];
  }
}
int query(int a, int b, int k, int l, int r, int c) {
  if (r <= a || b <= l)
    return 0;
  if (a <= l && r <= b)
    return node[k][c];
  else {
    bool vl = query(a, b, k * 2 + 1, l, (l + r) / 2, c);
    bool vr = query(a, b, k * 2 + 2, (l + r) / 2, r, c);
    return vl || vr;
  }
}

int main() {
  int N, q;
  cin >> N;
  string s;
  cin >> s;
  cin >> q;
  n = 1;
  init(s.size());
  rep(i, s.size()) update(i, 'a', s[i]);
  rep(i, q) {
    int type;
    cin >> type;
    if (type == 1) {
      int j;
      char c;
      cin >> j >> c;
      j--;
      update(j, s[j], c);
      s.replace(j, 1, 1, c);
    }
    if (type == 2) {
      int l, r;
      cin >> l >> r;
      int sum = 0;
      rep(j, 26) sum += query(l - 1, r, 0, 0, n, j);
      cout << sum << endl;
    }
  }
}

Fixed submission:
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <iostream>
#include <map>
#include <set>
#include <string>
#include <utility>
#include <vector>
typedef long long ll;
#define rep(i, n) for (int i = 0; i < n; i++)
using namespace std;
ll intpow(int n, int m) {
  if (m == 0)
    return 1;
  return n * intpow(n, m - 1);
}
ll gcd(ll n, ll m) {
  n = max(n, m);
  m = min(n, m);
  if (n % m == 0)
    return m;
  return gcd(m, n % m);
}
ll lcm(ll n, ll m) { return n * m / gcd(n, m); }
const int inf = 2147483647;
int n;
bool node[2000000][26];
void init(int n_) {
  while (n < n_)
    n *= 2;
  rep(i, 2 * n - 1) { rep(j, 26) node[i][j] = 0; }
}
void update(int i, char a, char b) {
  i += n - 1;
  int m1 = a - 97;
  int m2 = b - 97;
  node[i][m1] = 0;
  node[i][m2] = 1;
  while (i > 0) {
    i = (i - 1) / 2;
    node[i][m1] = node[i * 2 + 1][m1] || node[i * 2 + 2][m1];
    node[i][m2] = node[i * 2 + 1][m2] || node[i * 2 + 2][m2];
  }
}
int query(int a, int b, int k, int l, int r, int c) {
  if (r <= a || b <= l)
    return 0;
  if (a <= l && r <= b)
    return node[k][c];
  else {
    bool vl = query(a, b, k * 2 + 1, l, (l + r) / 2, c);
    bool vr = query(a, b, k * 2 + 2, (l + r) / 2, r, c);
    return vl || vr;
  }
}

int main() {
  int N, q;
  cin >> N;
  string s;
  cin >> s;
  cin >> q;
  n = 1;
  init(s.size());
  rep(i, s.size()) update(i, 'a', s[i]);
  rep(i, q) {
    int type;
    cin >> type;
    if (type == 1) {
      int j;
      char c;
      cin >> j >> c;
      j--;
      update(j, s[j], c);
      s.replace(j, 1, 1, c);
    }
    if (type == 2) {
      int l, r;
      cin >> l >> r;
      int sum = 0;
      rep(j, 26) sum += query(l - 1, r, 0, 0, n, j);
      cout << sum << endl;
    }
  }
}