Language: C++

#include <bits/stdc++.h>
//#include <boost/multiprecision/cpp_int.hpp>
//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
#pragma GCC optimize("O3")
#define REP(i,n) for(int i=0;i<n;i++)
#define REPP(i,n) for(int i=1;i<=n;i++)
#define ALL(obj) (obj).begin(), (obj).end()
#define EPS (1e-9)
#define INF (1e17)
#define PI (acos(-1))
//const double PI = acos(-1);
//const double EPS = 1e-15;
//long long INF=(long long)1E17;
#define i_7 (long long)(1e9+7)
//#define i_7 998'244'353
long mod(long a){
    long long c=a%i_7;
    if(c>=0)return c;
    return c+i_7;
}
long long po(long a, long b){
    if(b==0){
        return 1;
    }
    
    long long z = po(a,b/2);
    z = mod(z*z);
    if(b%2!=0){
        z = mod(a*z);
    }
    return z;
}
 
bool prime_(int n){
  if(n==1){
    return false;
  }else if(n==2){
    return true;
  }else{
    for(int i=2;i<=std::sqrt(n);i++){
      if(n%i==0){
        return false;
      }
    }
    return true;
  }
}
 
long long gcd_(long long a, long long b){
  if(a<b){
    std::swap(a,b);
  }
  if(a%b==0){
    return b;
  }else{
    return gcd_(b,a%b);
  }
}
 
long long lcm_(long long x, long long y){
  return (x/gcd_(x,y))*y;
}
 
using namespace std;
//using namespace boost::multiprecision;
//using namespace __gnu_pbds;

template <typename T>
class SegmentTree {
    using F = function<T(T, T)>;
    int n;
    F f;
    T t;
    vector <T> dat;
public:
    SegmentTree(F f, T t) : f(f), t(t) {}
    void init(int n_) {
        n = 1;
        while (n < n_) n <<= 1;
        dat.assign(n << 1, t);
    }
    void build(const vector <T> &v) {
        auto n_ = (int)v.size();
        init(n_);
        for (int i = 0; i < n_; i++) dat[n + i] = v[i];
        for (int i = n - 1; i > 0; i--) dat[i] = f(dat[(i << 1) | 0], dat[(i << 1) | 1]);
    }
    //k番目の値をxに変更する。
    void set_val(int k, T x) {
        dat[k += n] = x;
        while (k >>= 1) dat[k] = f(dat[(k << 1) | 0], dat[(k << 1) | 1]);
    }
    //[a,b)に対してfを適用する。
    T query(int a, int b) {
        T vl = t, vr = t;
        for (int l = a + n, r = b + n; l < r; l >>= 1, r >>= 1) {
            if (l & 1) vl = f(vl, dat[l++]);
            if (r & 1) vr = f(dat[--r], vr);
        }
        return f(vl, vr);
    }
};

int main(){
  int n;
  cin>>n;
  string s;
  cin>>s;
  auto f = [](long long a, long long b) { return a + b; };
  SegmentTree<long long> seg[26];
  REP(i, 26){
    seg[i] = SegmentTree<long long>(f, 0LL);
    seg[i].build(vector<long long>(n, 0LL));
  }
  REP(i, n){
    seg[s[i] - 'a'].set_val(i, 1LL);
  }
  char temp[n];
  REP(i, n){
    temp[i] = s[i];
  }
  int q;
  cin>>q;
  REP(h, q){
    int t;
    cin>>t;
    if(t == 1){
      int i;
      char c;
      cin>>i>>c;
      i--;
      if(temp[i] == c)continue;
      char x = temp[i];
      seg[x - 'a'].set_val(i, 0LL);
      seg[c - 'a'].set_val(i, 1LL);
      temp[i] = c;
    }else{
      int l, r;
      cin>>l>>r;
      l--;
      int res = 0;
      REP(i, 26){
        int num = seg[i].query(l, r);
        if(num > 0)res++;
      }
      cout<<res<<endl;
    }
  }
  return 0;
}


Compiler output:
a.cc: In function 'int main()':
a.cc:111:32: error: no matching function for call to 'SegmentTree<long long int>::SegmentTree()'
  111 |   SegmentTree<long long> seg[26];
      |                                ^
a.cc:77:5: note: candidate: 'SegmentTree<T>::SegmentTree(F, T) [with T = long long int; F = std::function<long long int(long long int, long long int)>]'
   77 |     SegmentTree(F f, T t) : f(f), t(t) {}
      |     ^~~~~~~~~~~
a.cc:77:5: note:   candidate expects 2 arguments, 0 provided
a.cc:70:7: note: candidate: 'SegmentTree<long long int>::SegmentTree(const SegmentTree<long long int>&)'
   70 | class SegmentTree {
      |       ^~~~~~~~~~~
a.cc:70:7: note:   candidate expects 1 argument, 0 provided
a.cc:70:7: note: candidate: 'SegmentTree<long long int>::SegmentTree(SegmentTree<long long int>&&)'
a.cc:70:7: note:   candidate expects 1 argument, 0 provided