Problem p02763 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <string>
#include <vector>

#define ll long long
#define MAX 25 * 1e13
#define N 200010

using namespace std;
int MOD = 1000000007;

#define MAX_Q 1001000

using namespace std;
int max_int = 1e9;

int dat[MAX_Q] = {0};
int n;
int init(int n_) {
  n = 1;
  while (n < n_)
    n *= 2;
  return 0;
}
int add(int k, char x) { // update with a point
  // [a,b) is target interval
  // x is the value added on interval
  // k is node id
  // [l,r) is current interval
  k += n - 1; // first n-2 node is not leaf,last n nodes are leaf,adjust target
              // position
  dat[k] = 0;
  dat[k] |= (1 << (x - 'a'));                 // update the very point
  while (k > 0) {                             // update to the root
    k = (k - 1) / 2;                          // find the father id
    dat[k] = dat[k * 2 + 1] | dat[k * 2 + 2]; // update the sum of father node
  }
  return 0;
}
int query_sum(int a, int b, int k, int l,
              int r) {    // query sum of value with a span
  if (b <= l || r <= a) { // no overlap part
    return 0;
  } else if (a <= l && r <= b) { // wholely overlap
    return dat[k];               // current node value
  } else {                       // partly overlap [l,r)
    int res = 0;
    res |= query_sum(a, b, k * 2 + 1, l, (l + r) / 2); // search left son
    res |= query_sum(a, b, k * 2 + 2, (l + r) / 2, r); // search right son

    return res;
  }
}
int print() {
  cout << "Array  : ";
  int pos = n - 1; // offset
  for (int i = 0; i < n; i++) {
    cout << dat[i + pos] << " ";
  }
  cout << endl;
  return 0;
}

string str;
int q;

int main() {

  cin.tie(0);
  ios::sync_with_stdio(false);

  int n_;

  cin >> n_;
  cin >> str;
  cin >> q;

  memset(dat, 0, sizeof(dat)); // initial all the data in the inerval tree
  int tmp;
  init(n_);
  for (int j = 0; j < n_; j++) {
    add(j, str[j]); // span: [ 0 , n )
  }
  char op1[100];
  int t = 0;
  // print();
  while (t < q) {
    t++;
    int op;
    cin >> op;
    if (op == 1) {

      int pt; // update by point

      string val;
      cin >> pt >> val;
      add(pt - 1, val[0]);
      // print();
      continue;
    }
    if (op == 2) {
      int l, r;
      cin >> l >> r;
      int ret = query_sum(l - 1, r, 0, 0, n);
      int cnt = 0;
      for (int i = 0; i < 26; i++) {
        if ((ret >> i) & 1)
          cnt++;
      }
      cout << cnt << endl;
      continue;
    }
  } // end for while op
  return 0;
} // end main


Fixed submission:
#include <algorithm>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <string>
#include <vector>

#define ll long long
#define MAX 25 * 1e13
#define N 200010

using namespace std;
int MOD = 1000000007;

#define MAX_Q 2001000

using namespace std;
int max_int = 1e9;

int dat[MAX_Q] = {0};
int n;
int init(int n_) {
  n = 1;
  while (n < n_)
    n *= 2;
  return 0;
}
int add(int k, char x) { // update with a point
  // [a,b) is target interval
  // x is the value added on interval
  // k is node id
  // [l,r) is current interval
  k += n - 1; // first n-2 node is not leaf,last n nodes are leaf,adjust target
              // position
  dat[k] = 0;
  dat[k] |= (1 << (x - 'a'));                 // update the very point
  while (k > 0) {                             // update to the root
    k = (k - 1) / 2;                          // find the father id
    dat[k] = dat[k * 2 + 1] | dat[k * 2 + 2]; // update the sum of father node
  }
  return 0;
}
int query_sum(int a, int b, int k, int l,
              int r) {    // query sum of value with a span
  if (b <= l || r <= a) { // no overlap part
    return 0;
  } else if (a <= l && r <= b) { // wholely overlap
    return dat[k];               // current node value
  } else {                       // partly overlap [l,r)
    int res = 0;
    res |= query_sum(a, b, k * 2 + 1, l, (l + r) / 2); // search left son
    res |= query_sum(a, b, k * 2 + 2, (l + r) / 2, r); // search right son

    return res;
  }
}
int print() {
  cout << "Array  : ";
  int pos = n - 1; // offset
  for (int i = 0; i < n; i++) {
    cout << dat[i + pos] << " ";
  }
  cout << endl;
  return 0;
}

string str;
int q;

int main() {

  cin.tie(0);
  ios::sync_with_stdio(false);

  int n_;

  cin >> n_;
  cin >> str;
  cin >> q;

  memset(dat, 0, sizeof(dat)); // initial all the data in the inerval tree
  int tmp;
  init(n_);
  for (int j = 0; j < n_; j++) {
    add(j, str[j]); // span: [ 0 , n )
  }
  char op1[100];
  int t = 0;
  // print();
  while (t < q) {
    t++;
    int op;
    cin >> op;
    if (op == 1) {

      int pt; // update by point

      string val;
      cin >> pt >> val;
      add(pt - 1, val[0]);
      // print();
      continue;
    }
    if (op == 2) {
      int l, r;
      cin >> l >> r;
      int ret = query_sum(l - 1, r, 0, 0, n);
      int cnt = 0;
      for (int i = 0; i < 26; i++) {
        if ((ret >> i) & 1)
          cnt++;
      }
      cout << cnt << endl;
      continue;
    }
  } // end for while op
  return 0;
} // end main