Language: C++

#include <bits/stdc++.h>

using namespace std;

using ll = long long;
using P = pair<ll, ll>;
using Graph = vector<vector<ll>>;
#define rep(i, n) for(ll i=0;i<(ll)(n);i++)
#define rep2(i, m, n) for(ll i=m;i<(ll)(n);i++)
#define rrep(i, n, m) for(ll i=n;i>=(ll)(m);i--)
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};
const int ddx[8] = {0, 1, 1, 1, 0, -1, -1, -1};
const int ddy[8] = {1, 1, 0, -1, -1, -1, 0, 1};
const ll MOD = 1000000007;
const ll INF = 1000000000000000000L;
#ifdef __DEBUG

/**
 * For DEBUG
 * https://github.com/ta7uw/cpp-pyprint
 */
#include "cpp-pyprint/pyprint.h"

#endif

template<class Monoid>
class SegmentTree {

public:
    /**
     * @param N size
     * @param e identity element
     * @param operation operation to merge `data`
     * @param updater operation to update `data`
     */
    SegmentTree(size_t N, Monoid e, function<Monoid(Monoid, Monoid)> operation,
                function<Monoid(Monoid, Monoid)> updater)
            : e(e), operation(operation), updater(move(updater)) {
        n = 1;
        while (n < N) {
            n *= 2;
        }
        data = vector<Monoid>(2 * n - 1, e);
        for (int i = n - 2; i >= 0; i--) {
            data[i] = operation(data[2 * i + 1], data[2 * i + 2]);
        }
    }

    /**
     * iの値をxに更新 ( 0-indexed )
     */
    void update(int i, Monoid x) {
        i += n - 1;
        data[i] = updater(data[i], x);
        while (i > 0) {
            i = (i - 1) / 2;
            data[i] = operation(data[i * 2 + 1], data[i * 2 + 2]);
        }
    }

    /**
     * [a, b)の区間でクエリを実行
     */
    Monoid query(int a, int b) {
        return query(a, b, 0, 0, n);
    }

    /**
     * 添字でアクセス( 0-indexed )
     */
    Monoid operator[](int i) {
        return data[i + n - 1];
    }

private:
    int n;
    vector<Monoid> data;
    Monoid e;
    function<Monoid(Monoid, Monoid)> operation;
    function<Monoid(Monoid, Monoid)> updater;

    Monoid query(int a, int b, int k, int l, int r) {
        // 交差しない
        if (r <= a || b <= l) return e;
        // 区間 [a, b) に l, r が含まれる
        if (a <= l && r <= b) return data[k];
        // 左の子
        Monoid c1 = query(a, b, 2 * k + 1, l, (l + r) / 2);
        // 右の子
        Monoid c2 = query(a, b, 2 * k + 2, (l + r) / 2, r);
        return operation(c1, c2);
    }
};

void Main() {
    ll N;
    cin >> N;
    string S;
    cin >> S;
    ll Q;
    cin >> Q;
    unordered_set<char> y = {};
    SegmentTree<unordered_set<char>&> segmentTree(N, y, [](unordered_set<char>& a, unordered_set<char>& b) {
                                                     for (char z: b) {
                                                         a.insert(z);
                                                     }
                                                     return a;
                                                 },
                                                 [](unordered_set<char>& a, unordered_set<char>& b) {
                                                     return b;
                                                 });
    rep(i, N) {
        char s = S[i];
        segmentTree.update(i, unordered_set<char>{s});
    }
    rep(q, Q) {
        ll s;
        cin >> s;
        if (s == 1) {
            ll j;
            char c;
            cin >> j >> c;
            segmentTree.update(j, unordered_set<char>{c});
        } else {
            ll l, r;
            cin >> l >> r;
            l--;
            auto X = segmentTree.query(l, r);
            cout << X.size() << '\n';
        }

    }
}

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(15);
    Main();
    return 0;
}


Compiler output:
In file included from /usr/include/x86_64-linux-gnu/c++/14/bits/c++allocator.h:33,
                 from /usr/include/c++/14/bits/allocator.h:46,
                 from /usr/include/c++/14/string:43,
                 from /usr/include/c++/14/bitset:52,
                 from /usr/include/x86_64-linux-gnu/c++/14/bits/stdc++.h:52,
                 from a.cc:1:
/usr/include/c++/14/bits/new_allocator.h: In instantiation of 'class std::__new_allocator<std::unordered_set<char>&>':
/usr/include/c++/14/bits/allocator.h:128:11:   required from 'class std::allocator<std::unordered_set<char>&>'
  128 |     class allocator : public __allocator_base<_Tp>
      |           ^~~~~~~~~
/usr/include/c++/14/bits/stl_vector.h:87:21:   required from 'struct std::_Vector_base<std::unordered_set<char>&, std::allocator<std::unordered_set<char>&> >'
   87 |         rebind<_Tp>::other _Tp_alloc_type;
      |                            ^~~~~~~~~~~~~~
/usr/include/c++/14/bits/stl_vector.h:428:11:   required from 'class std::vector<std::unordered_set<char>&, std::allocator<std::unordered_set<char>&> >'
  428 |     class vector : protected _Vector_base<_Tp, _Alloc>
      |           ^~~~~~
a.cc:78:20:   required from 'class SegmentTree<std::unordered_set<char>&>'
   78 |     vector<Monoid> data;
      |                    ^~~~
a.cc:104:51:   required from here
  104 |     SegmentTree<unordered_set<char>&> segmentTree(N, y, [](unordered_set<char>& a, unordered_set<char>& b) {
      |                                                   ^
/usr/include/c++/14/bits/new_allocator.h:70:26: error: forming pointer to reference type 'std::unordered_set<char>&'
   70 |       typedef _Tp*       pointer;
      |                          ^~~~~~~
/usr/include/c++/14/bits/new_allocator.h:71:26: error: forming pointer to reference type 'std::unordered_set<char>&'
   71 |       typedef const _Tp* const_pointer;
      |                          ^~~~~~~~~~~~~
/usr/include/c++/14/bits/new_allocator.h:126:7: error: forming pointer to reference type 'std::unordered_set<char>&'
  126 |       allocate(size_type __n, const void* = static_cast<const void*>(0))
      |       ^~~~~~~~
/usr/include/c++/14/bits/new_allocator.h:156:7: error: forming pointer to reference type 'std::unordered_set<char>&'
  156 |       deallocate(_Tp* __p, size_type __n __attribute__ ((__unused__)))
      |       ^~~~~~~~~~
/usr/include/c++/14/bits/allocator.h: In instantiation of 'class std::allocator<std::unordered_set<char>&>':
/usr/include/c++/14/bits/stl_vector.h:87:21:   required from 'struct std::_Vector_base<std::unordered_set<char>&, std::allocator<std::unordered_set<char>&> >'
   87 |         rebind<_Tp>::other _Tp_alloc_type;
      |                            ^~~~~~~~~~~~~~
/usr/include/c++/14/bits/stl_vector.h:428:11:   required from 'class std::vector<std::unordered_set<char>&, std::allocator<std::unordered_set<char>&> >'
  428 |     class vector : protected _Vector_base<_Tp, _Alloc>
      |           ^~~~~~
a.cc:78:20:   required from 'class SegmentTree<std::unordered_set<char>&>'
   78 |     vector<Monoid> data;
      |                    ^~~~
a.cc:104:51:   required from here
  104 |     SegmentTree<unordered_set<char>&> segmentTree(N, y, [](unordered_set<char>& a, unordered_set<char>& b) {
      |                                                   ^
/usr/include/c++/14/bits/allocator.h:137:26: error: forming pointer to reference type 'std::unordered_set<char>&'
  137 |       typedef _Tp*       pointer;
      |                          ^~~~~~~
/usr/include/c++/14/bits/allocator.h:138:26: error: forming pointer to reference type 'std::unordered_set<char>&'
  138 |       typedef const _Tp* const_pointer;
      |                          ^~~~~~~~~~~~~
In file included from /usr/include/c++/14/ext/alloc_traits.h:34,
                 from /usr/include/c++/14/bits/basic_string.h:39,
                 from /usr/include/c++/14/string:54:
/usr/include/c++/14/bits/alloc_traits.h: In instantiation of 'struct std::allocator_traits<std::allocator<std::unordered_set<char>&> >':
/usr/include/c++/14/ext/alloc_traits.h:45:10:   required from 'struct __gnu_cxx::__alloc_traits<std::allocator<std::unordered_set<char>&>, std::unordered_set<char>&>'
   45 |   struct __alloc_traits
      |          ^~~~~~~~~~~~~~
/usr/include/c++/14/bits/stl_vector.h:87:21:   required from 'struct std::_Vector_base<std::unordered_set<char>&, std::allocator<std::unordered_set<char>&> >'
   87 |         rebind<_Tp>::other _Tp_alloc_type;
      |                            ^~~~~~~~~~~~~~
/usr/include/c++/14/bits/stl_vector.h:428:11:   required from 'class std::vector<std::unordered_set<char>&, std::allocator<std::unordered_set<char>&> >'
  428 |     class vector : protected _Vector_base<_Tp, _Alloc>
      |           ^~~~~~
a.cc:78:20:   required from 'class SegmentTree<std::unordered_set<char>&>'
   78 |     vector<Monoid> data;
      |                    ^~~~
a.cc:104:51:   required from here
  104 |     SegmentTree<unordered_set<char>&> segmentTree(N, y, [](unordered_set<char>& a, unordered_set<char>& b) {
      |                                                   ^
/usr/include/c++/14/bits/alloc_traits.h:470:13: error: forming pointer to reference type 'std::unordered_set<char>&'
  470 |       using pointer = _Tp*;
      |             ^~~~~~~
/usr/include/c++/14/bits/alloc_traits.h:473:13: error: forming pointer to reference type 'std::unordered_set<char>&'
  473 |       using const_pointer = const _Tp*;
      |             ^~~~~~~~~~~~~
/usr/include/c++/14/ext/alloc_traits.h: In instantiation of 'struct __gnu_cxx::__alloc_traits<std::allocator<std::unordered_set<char>&>, std::unordered_set<char>&>':
/usr/include/c++/14/bits/stl_vector.h:87:21:   required from 'struct std::_Vector_base<std::unordered_set<char>&, std::allocator<std::unordered_set<char>&> >'
   87 |         rebind<_Tp>::other _Tp_alloc_type;
      |                            ^~~~~~~~~~~~~~
/usr/include/c++/14/bits/stl_vector.h:428:11:   required from 'class std::vector<std::unordered_set<char>&, std::allocator<std::unordered_set<char>&> >'
  428 |     class vector : protected _Vector_base<_Tp, _Alloc>
      |           ^~~~~~
a.cc:78:20:   required from 'class SegmentTree<std::unordered_set<char>&>'
   78 |     vector<Monoid> data;
      |                    ^~~~
a.cc:104:51:   required from here
  104 |     SegmentTree<unordered_set<char>&> segmentTree(N, y, [](unordered_set<char>& a, unordered_set<char>& b) {
      |                                                   ^
/usr/include/c++/14/ext/alloc_traits.h:61:23: error: 'allocate' has not been declared in '__gnu_cxx::__alloc_traits<std::allocator<std::unordered_set<char>&>, std::unordered_set<char>&>::_Base_type'
   61 |     using _Base_type::allocate;
      |                       ^~~~~~~~
/usr/include/c++/14/ext/alloc_traits.h:62:23: error: 'deallocate' has not been declared in '__gnu_cxx::__alloc_traits<std::allocator<std::unordered_set<char>&>, std::unordered_set<char>&>::_Base_type'
   62 |     using _Base_type::deallocate;
      |                       ^~~~~~~~~~
In file included from /usr/include/c++/14/vector:66,
                 from /usr/include/c++/14/functional:64,
                 from /usr/include/x86_64-linux-gnu/c++/14/bits/stdc++.h:53:
/usr/include/c++/14/bits/stl_vector.h: In instantiation of 'class std::vector<std::unordered_set<char>&, std::allocator<std::unordered_set<char>&> >':
a.cc:78:20:   required from 'class SegmentTree<std::unordered_set<char>&>'
   78 |     vector<Monoid> data;
      |                    ^~~~
a.cc:104:51:   required from here
  104 |     SegmentTree<unordered_set<char>&> segmentTree(N, y, [](unordered_set<char>& a, unordered_set<char>& b) {
      |                                                   ^
/usr/include/c++/14/bits/stl_vector.h:518:20: error: '_M_allocate' has not been declared in 'std::vector<std::unordered_set<char>&, std::allocator<std::unordered_set<char>&> >::_Base'
  518 |       using _Base::_M_allocate;
      |                    ^~~~~~~~~~~
/usr/include/c++/14/bits/stl_vector.h:519:20: error: '_M_deallocate' has not been declared in 'std::vector<std::unordered_set<char>&, std::allocator<std::unordered_set<char>&> >::_Base'
  519 |       using _Base::_M_deallocate;
      |                    ^~~~~~~~~~~~~
/usr/include/c++/14/bits/stl_vector.h:1262:7: error: forming pointer to reference type 'std::unordered_set<char>&'
 1262 |       data() _GLIBCXX_NOEXCEPT
      |       ^~~~
/usr/include/c++/14/bits/stl_vector.h:1267:7: error: forming pointer to reference type 'std::unordered_set<char>&'
 1267 |       data() const _GLIBCXX_NOEXCEPT
      |       ^~~~
/usr/include/c++/14/bits/stl_vector.h:1300:7: error: 'void std::vector<_Tp, _Alloc>::push_back(value_type&&) [with _Tp = std::unordered_set<char>&; _Alloc = std::allocator<std::unordered_set<char>&>; value_type = std::unordered_set<char>&]' cannot be overloaded with 'void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = std::unordered_set<char>&; _Alloc = std::allocator<std::unordered_set<char>&>; value_type = std::unordered_set<char>&]'
 1300 |       push_back(value_type&& __x)
      |       ^~~~~~~~~
/usr/include/c++/14/bits/stl_vector.h:1283:7: note: previous declaration 'void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = std::unordered_set<char>&; _Alloc = std::allocator<std::unordered_set<char>&>; value_type = std::unordered_set<char>&]'
 1283 |       push_back(const value_type& __x)
      |       ^~~~~~~~~
a.cc: In function 'void Main()':
a.cc:112:51: error: no matching function for call to 'SegmentTree<std::unordered_set<char>&>::SegmentTree(ll&, std::unordered_set<char>&, Main()::<lambda(std::unordered_set<char>&, std::unordered_set<char>&)>, Main()::<lambda(std::unordered_set<char>&, std::unordered_set<char>&)>)'
  112 |                                                  });
      |                                                   ^
a.cc:37:5: note: candidate: 'SegmentTree<Monoid>::SegmentTree(size_t, Monoid, std::function<Monoid(Monoid, Monoid)>, std::function<Monoid(Monoid, Monoid)>) [with Monoid = std::unordered_set<char>&; size_t = long unsigned int]'
   37 |     SegmentTree(size