Problem p02763 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <cmath>
#include <complex>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <typeinfo>
#include <unordered_map>
#include <utility>
#include <vector>
using namespace std;

using ll = long long;
using vll = vector<ll>;
using pll = pair<ll, ll>;
using qll = queue<ll>;
using vb = vector<bool>;
using mll = map<ll, ll>;
using sll = stack<ll>;
#define REP(i, n) for (ll i(0); (i) < (n); (i)++)
#define rep(i, n) for (ll i(0); (i) < (n); (i)++)
#define ALL(a) a.begin(), a.end()
#define enld endl //* missspell check
const ll INF = 1LL << 60;
const ll sqrtN = 512; //* 512*512=262144 > 10^5

struct RSQ {
  ll N, K; //* N length of data, K number of buckets
  string data;
  vector<vll> bucketSum;
  //* allocate memory with zeros
  void init(ll n) {
    N = n;
    K = (n + sqrtN - 1) / sqrtN; //* number of buckets = ceil(n/sqrtN)
    // data.assign(K * sqrtN, '0');
    data = string(K * sqrtN, '0');
    bucketSum.assign(K, vll(26, 0));
  }
  //* constructor
  RSQ(ll n) { init(n); }
  //* constructor with init vector data
  RSQ(ll n, string &a) {
    init(n);
    REP(i, n) { data[i] = a[i]; }
    REP(k, K) {
      for (ll j = k * sqrtN; j < (k + 1) * sqrtN; j++) {
        bucketSum[k][data[j] - 'a']++;
      }
    }
  }
  //* update (add(i, x) -> a[i]+= x)
  void update(ll i, char x) {
    ll k = i / sqrtN; //* corresponding bucket
    char old = data[i];
    data[i] = x;
    bucketSum[k][old - 'a']--;
    bucketSum[k][data[i] - 'a']++;
  }
  //* getSum(s, t)-> return a[s]+a[s+1]+...+a[t-1]
  //* [x, y)
  ll getSum(ll x, ll y) {
    ll cnt = 0;
    vll tmpChar(26, 0);
    REP(k, K) {
      ll l = k * sqrtN, r = (k + 1) * sqrtN; //* bucket [l, r)
      if (r <= x || y <= l)                  //* no intersection
        continue;
      if (x <= l && r <= y) { //* [l, r) in [x, y)
        REP(ch, 26) { tmpChar[ch] += bucketSum[k][ch]; }
      } else { //* has intersection on boundary
        for (ll i = max(l, x); i < min(r, y); i++) {
          tmpChar[data[i] - 'a']++;
        }
      }
    }
    REP(ch, 26) cnt += ((tmpChar[ch] > 0) ? 1 : 0);
    return cnt;
  }
};

int main() {
  ll N;
  cin >> N;
  string S;
  cin >> S;
  RSQ st(N, S);

  ll Q;
  cin >> Q;
  REP(q, Q) {
    ll type;
    cin >> type;
    if (type == 1) {
      ll i;
      cin >> i;
      i--;
      char c;
      cin >> c;
      st.update(i, c);
    }
    if (type == 2) {
      ll l, r;
      cin >> l >> r;
      l--;
      cout << st.getSum(l, r) << endl;
    }
  }

  return 0;
}


Fixed submission:
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <cmath>
#include <complex>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <typeinfo>
#include <unordered_map>
#include <utility>
#include <vector>
using namespace std;

using ll = long long;
using vll = vector<ll>;
using pll = pair<ll, ll>;
using qll = queue<ll>;
using vb = vector<bool>;
using mll = map<ll, ll>;
using sll = stack<ll>;
#define REP(i, n) for (ll i(0); (i) < (n); (i)++)
#define rep(i, n) for (ll i(0); (i) < (n); (i)++)
#define ALL(a) a.begin(), a.end()
#define enld endl //* missspell check
const ll INF = 1LL << 60;
const ll sqrtN = 512; //* 512*512=262144 > 10^5

struct RSQ {
  ll N, K; //* N length of data, K number of buckets
  string data;
  vector<vll> bucketSum;
  //* allocate memory with zeros
  void init(ll n) {
    N = n;
    K = (n + sqrtN - 1) / sqrtN; //* number of buckets = ceil(n/sqrtN)
    // data.assign(K * sqrtN, '0');
    data = string(K * sqrtN, '0');
    bucketSum.assign(K, vll(26, 0));
  }
  //* constructor
  RSQ(ll n) { init(n); }
  //* constructor with init vector data
  RSQ(ll n, string &a) {
    init(n);
    REP(i, n) { data[i] = a[i]; }
    REP(k, K) {
      for (ll j = k * sqrtN; j < min(n, (k + 1) * sqrtN); j++) {
        bucketSum[k][data[j] - 'a']++;
      }
    }
  }
  //* update (add(i, x) -> a[i]+= x)
  void update(ll i, char x) {
    ll k = i / sqrtN; //* corresponding bucket
    char old = data[i];
    data[i] = x;
    bucketSum[k][old - 'a']--;
    bucketSum[k][data[i] - 'a']++;
  }
  //* getSum(s, t)-> return a[s]+a[s+1]+...+a[t-1]
  //* [x, y)
  ll getSum(ll x, ll y) {
    ll cnt = 0;
    vll tmpChar(26, 0);
    REP(k, K) {
      ll l = k * sqrtN, r = (k + 1) * sqrtN; //* bucket [l, r)
      if (r <= x || y <= l)                  //* no intersection
        continue;
      if (x <= l && r <= y) { //* [l, r) in [x, y)
        REP(ch, 26) { tmpChar[ch] += bucketSum[k][ch]; }
      } else { //* has intersection on boundary
        for (ll i = max(l, x); i < min(r, y); i++) {
          tmpChar[data[i] - 'a']++;
        }
      }
    }
    REP(ch, 26) cnt += ((tmpChar[ch] > 0) ? 1 : 0);
    return cnt;
  }
};

int main() {
  ll N;
  cin >> N;
  string S;
  cin >> S;
  RSQ st(N, S);

  ll Q;
  cin >> Q;
  REP(q, Q) {
    ll type;
    cin >> type;
    if (type == 1) {
      ll i;
      cin >> i;
      i--;
      char c;
      cin >> c;
      st.update(i, c);
    }
    if (type == 2) {
      ll l, r;
      cin >> l >> r;
      l--;
      cout << st.getSum(l, r) << endl;
    }
  }

  return 0;
}