Problem:
 Score : 500 points    Problem Statement You are given a string S of length N consisting of lowercase English letters.  Process Q queries of the following two types:   Type 1 : change the i_q -th character of S to c_q . (Do nothing if the i_q -th character is already c_q .)  Type 2 : answer the number of different characters occurring in the substring of S between the l_q -th and r_q -th characters (inclusive).       Constraints  N , Q , i_q , l_q , and r_q are integers.  S is a string consisting of lowercase English letters.  c_q is a lowercase English letter.  1 \leq N \leq 500000  1 \leq Q \leq 20000  |S| = N  1 \leq i_q \leq N  1 \leq l_q \leq r_q \leq N  There is at least one query of type 2 in each testcase.         Input Input is given from Standard Input in the following format:  N  S  Q  Query_1  \vdots  Query_Q   Here, Query_i in the 4 -th through (Q+3) -th lines is one of the following:  1  i_q  c_q   2  l_q  r_q       Output For each query of type 2 , print a line containing the answer.        Sample Input 1 7
abcdbbd
6
2 3 6
1 5 z
2 1 1
1 4 a
1 7 d
2 1 7      Sample Output 1 3
1
5  In the first query, cdbb contains three kinds of letters: b , c , and d , so we print 3 .  In the second query, S is modified to abcdzbd .  In the third query, a contains one kind of letter: a , so we print 1 .  In the fourth query, S is modified to abcazbd .  In the fifth query, S does not change and is still abcazbd .  In the sixth query, abcazbd contains five kinds of letters: a , b , c , d , and z , so we print 5 .

Solution (Python):
alp="abcdefghijklmnopqrstuvwxyz"

n=int(input())
s=list(input())
q=int(input())


def segfunc(x, y):
    return x+y



ide_ele = 0




class SegTree:
    """
    init(init_val, ide_ele): 配列init_valで初期化 O(N)
    update(k, x): k番目の値をxに更新 O(logN)
    query(l, r): 区間[l, r)をsegfuncしたものを返す O(logN)
    """
    def __init__(self, init_val, segfunc, ide_ele):
        """
        init_val: 配列の初期値
        segfunc: 区間にしたい操作
        ide_ele: 単位元
        n: 要素数
        num: n以上の最小の2のべき乗
        tree: セグメント木(1-index)
        """
        n = len(init_val)
        self.segfunc = segfunc
        self.ide_ele = ide_ele
        self.num = 1 << (n - 1).bit_length()
        self.tree = [ide_ele] * 2 * self.num
        
        for i in range(n):
            self.tree[self.num + i] = init_val[i]
        
        for i in range(self.num - 1, 0, -1):
            self.tree[i] = self.segfunc(self.tree[2 * i], self.tree[2 * i + 1])

    def update(self, k, x):
        """
        k番目の値をxに更新
        k: index(0-index)
        x: update value
        """
        k += self.num
        self.tree[k] = x
        while k > 1:
            self.tree[k >> 1] = self.segfunc(self.tree[k], self.tree[k ^ 1])
            k >>= 1

    def query(self, l, r):
        """
        [l, r)のsegfuncしたものを得る
        l: index(0-index)
        r: index(0-index)
        """
        res = self.ide_ele

        l += self.num
        r += self.num
        while l < r:
            if l & 1:
                res = self.segfunc(res, self.tree[l])
                l += 1
            if r & 1:
                res = self.segfunc(res, self.tree[r - 1])
            l >>= 1
            r >>= 1
        return res

app=[[0 for i in range(n)] for i in range(26)]
for i in range(n):
    app[alp.index(s[i])][i]=1

appapp=[None for i in range(26)]
for i in range(26):
    appapp[i]=SegTree(app[i], segfunc, ide_ele)

for i in range(q):
    que=input().split()
    if que[0]=="1":
        for tre in appapp:
            tre.update(int(que[1])-1,0)
        nex=alp.index(que[2])
        appapp[nex].update(int(que[1])-1,1)
    else:
        tab=0
        for tre in appapp:
            if tre.query(int(que[1])-1,int(que[2]))>0:
                tab+=1
        print(tab)

Solution (Python):
import sys
input = lambda : sys.stdin.readline().rstrip()
sys.setrecursionlimit(max(1000, 10**9))
write = lambda x: sys.stdout.write(x+"\n")



n = int(input())
s = input()
q = int(input())


def init(bit, values):
    for i,v in enumerate(values):
        update(bit,i,v)

def query(bit,i):
    res = 0
    while i > 0:
        res += bit[i]
        i -= i&(-i)
    return res


def update(bit,i,x):
    while i <= len(bit)-1:
        bit[i] += x
        i += i&(-i)
    return

l = [chr(v) for v in range(ord("a"), ord("z")+1)]
d = {c: [0] * (n+1) for c in l}
for i,c in enumerate(s):
    update(d[c], i+1, 1)
s = list(s)
ans = []
for i in range(q):
    v,i,c = input().split()
    if v=="1":
        i = int(i)-1
        if d[s[i]][i+1]>=1:
            update(d[s[i]], i+1, -1)
        update(d[c], i+1, 1)
        s[i] = c
    else:
        ll,rr = int(i),int(c)
        val = sum(query(d[c], rr) - query(d[c], ll-1) >= 1 for c in l)
        ans.append(val)
write("\n".join(map(str, ans)))

Solution (Python):
import sys
import numpy as np

read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines

seg_unit = 0


def seg_f(x, y):
    return x | y


def build(seg, raw_data):
    N = len(seg) // 2
    seg[N:] = raw_data
    for i in range(N - 1, 0, -1):
        seg[i] = seg_f(seg[i << 1], seg[i << 1 | 1])


def set_val(seg, i, x):
    N = len(seg) // 2
    i += N
    seg[i] = x
    while i > 1:
        i >>= 1
        seg[i] = seg_f(seg[i << 1], seg[i << 1 | 1])


def fold(seg, l, r):
    vl = vr = 0
    N = len(seg) // 2
    l, r = l + N, r + N
    while l < r:
        if l & 1:
            vl = seg_f(vl, seg[l])
            l += 1
        if r & 1:
            r -= 1
            vr = seg_f(seg[r], vr)
        l, r = l >> 1, r >> 1
    return seg_f(vl, vr)

def main(N, S, query):
    seg = np.zeros(N + N, np.int64)
    build(seg, 1 << S)
    for q in query:
        t, a, b = q.split()
        if t == b'1':
            a, b = int(a) - 1, ord(b) - ord('a')
            set_val(seg, a, 1 << b)
        else:
            a, b = int(a) - 1, int(b)
            x = fold(seg, a, b)
            print(bin(x).count('1'))

if sys.argv[-1] == 'ONLINE_JUDGE':
    import numba
    from numba.pycc import CC
    i8 = numba.int64
    cc = CC('my_module')

    def cc_export(f, signature):
        cc.export(f.__name__, signature)(f)
        return numba.njit(f)

    seg_f = cc_export(seg_f, (i8, i8))
    build = cc_export(build, (i8[:], i8[:]))
    set_val = cc_export(set_val, (i8[:], i8, i8))
    fold = cc_export(fold, (i8[:], i8, i8))
    cc.compile()

from my_module import seg_f, build, set_val, fold

N = int(readline())
S = np.array(list(readline().rstrip()), np.int64) - ord('a')
query = readlines()[1:]

main(N, S, query)

Solution (Python):
import sys, math
input = sys.stdin.readline
rs = lambda: input().strip()
ri = lambda: int(input())
rl = lambda: list(map(int, input().split()))
mod = 10**9 + 7

class BIT:
    def __init__(self, n):
        self.n = n
        self.nums = [0] * (n+1)
        
    def add(self, i, x):
        n, nums = self.n, self.nums
        i += 1
        while i <= n:
            nums[i] += x
            i += i & -i
    
    def sum(self, i):
        nums = self.nums
        s = 0
        i += 1
        while i:
            s += nums[i]
            i -= i & -i
        return s
    
    def search(self, x):
        n, nums = self.n, self.nums
        s, p = 0, 0
        for i in range(n.bit_length(), -1, -1):
            np = p + (1<<i)
            if np <= n and s+nums[np] < x:
                s += nums[np]
                p = np
        return p


N = ri()
S = rs()
Q = ri()
queries = []
for i in range(Q):
	q = rs().split()
	if q[0] == '1':
		q = (int(q[0]), int(q[1])-1, q[2])
	else:
		q = (int(q[0]), int(q[1])-1, int(q[2])-1)
	queries.append(q)

import collections
h = collections.defaultdict(lambda: BIT(N))

S = list(S)
for i, s in enumerate(S):
	h[s].add(i, 1)
for q in queries:
	if q[0] == 1:
		i, c = q[1], q[2]
		h[S[i]].add(i, -1)
		h[c].add(i, 1)
		S[i] = c
	else:
		l, r = q[1], q[2]
		cnt = 0
		for c, bit in h.items():
			if bit.sum(r) - bit.sum(l-1) > 0:
				cnt += 1
		print(cnt)

Solution (Python):
class BinaryIndexedTree:
    def __init__(self,n,default = 0):
        self.s = [default]*(n+1)
        self.n = n
    
    def add(self,val,idx):
        while idx < self.n+1:
            self.s[idx] = self.s[idx] + val
            idx += idx&(-idx)
        return
    
    def get(self,idx):
        res = 0
        while idx > 0:
            res = res + self.s[idx]
            idx -= idx&(-idx)
        return res

import sys
sys.setrecursionlimit(10**6)
input = sys.stdin.readline

n = int(input())
S = [ord(s) - ord('a') for s in input()[:-1]]

BIT = [BinaryIndexedTree(n) for i in range(26)]

for i,s in enumerate(S):
    BIT[s].add(1,i+1)

Q = int(input())
ans = []
for _ in range(Q):  
    flag,x,y = input().split()

    if flag == "1":
        i = int(x)
        c = ord(y) - ord('a')
        BIT[S[i-1]].add(-1,i)
        BIT[c].add(1,i)
        S[i-1] = c
    else:
        l = int(x)
        r = int(y)
        res = 0
        for i in range(26):
            
            res += (BIT[i].get(r) > BIT[i].get(l-1))
        ans.append(str(res))
print("\n".join(ans))

Solution (Python):
import sys

import math
import collections

import bisect
import itertools
import fractions

import copy

import decimal

import queue



sys.setrecursionlimit(10000001)
INF = 10 ** 16
MOD = 10 ** 9 + 7


ni = lambda: int(sys.stdin.readline())
ns = lambda: map(int, sys.stdin.readline().split())
na = lambda: list(map(int, sys.stdin.readline().split()))



def main():
    n = ni()
    s = list(input())
    q = ni()

    alphabet_idx = {}
    for i in range(26):
        alphabet_idx[i] = []

    for i, si in enumerate(s):
        alphabet_idx[ord(si) - ord("a")].append(i)

    for _ in range(q):
        qi, a, b = input().split()
        qi, a = int(qi), int(a)

        if qi == 1:
            a -= 1
            if s[a] == b:
                continue
            del_char = ord(s[a]) - ord("a")
            del_idx = bisect.bisect_left(alphabet_idx[del_char], a)
            del alphabet_idx[del_char][del_idx]

            insert_char = ord(b) - ord("a")
            insert_idx = bisect.bisect_left(alphabet_idx[insert_char], a)
            alphabet_idx[insert_char].insert(insert_idx, a)

            s[a] = b

        if qi == 2:
            b = int(b)
            a -= 1
            b -= 1
            ans = 0

            for i in range(26):
                a_idx = bisect.bisect_left(alphabet_idx[i], a)
                if a_idx < len(alphabet_idx[i]):
                    if alphabet_idx[i][a_idx] <= b:
                        ans += 1

            print(ans)


if __name__ == '__main__':
    main()

Solution (Python):
import sys

import math
import collections

import bisect
import itertools
import fractions

import copy

import decimal

import queue



sys.setrecursionlimit(10000001)
INF = 10 ** 16
MOD = 10 ** 9 + 7


ni = lambda: int(sys.stdin.readline())
ns = lambda: map(int, sys.stdin.readline().split())
na = lambda: list(map(int, sys.stdin.readline().split()))



def main():
    n = ni()
    s = list(input())
    q = ni()

    alphabet_idx = {}
    for i in range(26):
        alphabet_idx[i] = []

    for i, si in enumerate(s):
        alphabet_idx[ord(si) - ord("a")].append(i)

    for _ in range(q):
        qi, a, b = input().split()
        qi, a = int(qi), int(a)

        if qi == 1:
            a -= 1
            if s[a] == b:
                continue
            current_char = ord(s[a]) - ord("a")
            del_idx = bisect.bisect_left(alphabet_idx[current_char], a)
            del alphabet_idx[current_char][del_idx]

            insert_idx = bisect.bisect_left(alphabet_idx[ord(b) - ord("a")], a)
            alphabet_idx[ord(b) - ord("a")].insert(insert_idx, a)

            s[a] = b

        if qi == 2:
            b = int(b)
            a -= 1
            b -= 1
            ans = 0

            for i in range(26):
                a_idx = bisect.bisect_left(alphabet_idx[i], a)
                if a_idx < len(alphabet_idx[i]):
                    if alphabet_idx[i][a_idx] <= b:
                        ans += 1

            print(ans)


if __name__ == '__main__':
    main()

Solution (Python):
from bisect import bisect_left,bisect_right

TO_ACII = 97

N = int(input())
S = ["0"] + list(input())
Q = int(input())

ABC = [[]for i in range(0,26,1)]

for i in range(1,N+1,1):
    ABC[ord(S[i])-TO_ACII].append(i)

ans = []
for i in range(0,Q,1):
    q = list(input().split())
    if q[0]=="1":
        changed = S[int(q[1])]
        ABC[ord(changed)-TO_ACII].pop(bisect_left(ABC[ord(changed)-TO_ACII],int(q[1])))
        ABC[ord(q[2])-TO_ACII].insert(bisect_left(ABC[ord(q[2])-TO_ACII],int(q[1])),int(q[1]))
        S[int(q[1])]=q[2]
    else:
        tmpans = 0
        for i in range(0,26,1):

            if bisect_right(ABC[i],int(q[1])-1)<len(ABC[i]) and int(q[2]) >= ABC[i][bisect_right(ABC[i],int(q[1])-1)]:
                tmpans+=1
        ans.append(tmpans)

for i in range(0,len(ans),1):
    print(ans[i])

Solution (Python):


class SegTree():
    
    def __init__(self, lists, function, basement):
        self.n = len(lists)
        self.K = (self.n-1).bit_length()
        self.f = function
        self.b = basement
        self.seg = [basement]*(2**(self.K+1)+1)
        X = 2**self.K
        for i, v in enumerate(lists):
            self.seg[i+X] = v
        for i in range(X-1, 0, -1):
            self.seg[i] = self.f(self.seg[i << 1], self.seg[i << 1 | 1])

    def update(self, k, value):
        X = 2**self.K
        k += X
        self.seg[k] = value
        while k:
            k = k >> 1
            self.seg[k] = self.f(self.seg[k << 1], self.seg[(k << 1) | 1])

    def query(self, L, R):
        num = 2**self.K
        L += num
        R += num
        vL = self.b
        vR = self.b
        while L < R:
            if L & 1:
                vL = self.f(vL, self.seg[L])
                L += 1
            if R & 1:
                R -= 1
                vR = self.f(self.seg[R], vR)
            L >>= 1
            R >>= 1
        return self.f(vL, vR)

    def find_max_index(self, L, R, X):
        
        return self.fMi(L, R, X, 1, 0, 2**self.K)

    def find_min_index(self, L, R, X):
        
        return self.fmi(L, R, X, 1, 0, 2**self.K)

    def fMi(self, a, b, x, k, l, r):
        if self.seg[k] > x or r <= a or b <= l:
            return -1
        else:
            if k >= 2**self.K:
                return k-2**self.K
            else:
                vr = self.fMi(a, b, x, (k << 1) | 1, (l + r) // 2, r)
                if vr != -1:
                    return vr
                return self.fMi(a, b, x, k << 1, l, (l + r) // 2)

    def fmi(self, a, b, x, k, l, r):
        if self.seg[k] > x or r <= a or b <= l:
            return -1
        else:
            if k >= 2**self.K:
                return k-2**self.K
            else:
                vl = self.fmi(a, b, x, k << 1, l, (l+r)//2)
                if vl != -1:
                    return vl
                return self.fmi(a, b, x, k << 1 | 1, (l+r)//2, r)
N = int(input())
S = list(input())
Q = int(input())
que = [tuple(input().split()) for i in range(Q)]
alpha = "abcdefghijklmnopqrstuvwxyz"
Data = {alpha[i]: [0]*N for i in range(26)}
for i in range(N):
    Data[S[i]][i] += 1
SEG = {alpha[i]: SegTree(Data[alpha[i]], max, 0) for i in range(26)}
for X, u, v in que:
    if X == "1":
        u = int(u)-1
        NOW = S[u]
        S[u] = v
        SEG[NOW].update(u, 0)
        SEG[v].update(u,1)
    else:
        s, t = int(u)-1, int(v)-1
        res = 0
        for j in range(26):
            res += SEG[alpha[j]].query(s, t+1)
        print(res)

Solution (Python):


class SegTree():
    
    def __init__(self, lists, function, basement):
        self.n = len(lists)
        self.K = (self.n-1).bit_length()
        self.f = function
        self.b = basement
        self.seg = [basement]*(2**(self.K+1)+1)
        X = 2**self.K
        for i, v in enumerate(lists):
            self.seg[i+X] = v
        for i in range(X-1, 0, -1):
            self.seg[i] = self.f(self.seg[i << 1], self.seg[i << 1 | 1])

    def update(self, k, value):
        X = 2**self.K
        k += X
        self.seg[k] = value
        while k:
            k = k >> 1
            self.seg[k] = self.f(self.seg[k << 1], self.seg[(k << 1) | 1])

    def query(self, L, R):
        num = 2**self.K
        L += num
        R += num
        vL = self.b
        vR = self.b
        while L < R:
            if L & 1:
                vL = self.f(vL, self.seg[L])
                L += 1
            if R & 1:
                R -= 1
                vR = self.f(self.seg[R], vR)
            L >>= 1
            R >>= 1
        return self.f(vL, vR)

    def find_max_index(self, L, R, X):
        
        return self.fMi(L, R, X, 1, 0, 2**self.K)

    def find_min_index(self, L, R, X):
        
        return self.fmi(L, R, X, 1, 0, 2**self.K)

    def fMi(self, a, b, x, k, l, r):
        if self.seg[k] > x or r <= a or b <= l:
            return -1
        else:
            if k >= 2**self.K:
                return k-2**self.K
            else:
                vr = self.fMi(a, b, x, (k << 1) | 1, (l + r) // 2, r)
                if vr != -1:
                    return vr
                return self.fMi(a, b, x, k << 1, l, (l + r) // 2)

    def fmi(self, a, b, x, k, l, r):
        if self.seg[k] > x or r <= a or b <= l:
            return -1
        else:
            if k >= 2**self.K:
                return k-2**self.K
            else:
                vl = self.fmi(a, b, x, k << 1, l, (l+r)//2)
                if vl != -1:
                    return vl
                return self.fmi(a, b, x, k << 1 | 1, (l+r)//2, r)
N = int(input())
S = list(input())
Q = int(input())
que = [tuple(input().split()) for i in range(Q)]
alpha = "abcdefghijklmnopqrstuvwxyz"
Data = {alpha[i]: [0]*N for i in range(26)}
for i in range(N):
    Data[S[i]][i] += 1
SEG = {alpha[i]: SegTree(Data[alpha[i]], max, 0) for i in range(26)}
for X, u, v in que:
    if X == "1":
        u = int(u)-1
        NOW = S[u]
        S[u] = v
        SEG[NOW].update(u, 0)
        SEG[v].update(u,1)
    else:
        s, t = int(u)-1, int(v)-1
        res = 0
        for j in range(26):
            res += SEG[alpha[j]].query(s, t+1)
        print(res)

Solution (Python):
import bisect
import sys
input = sys.stdin.readline

def solve():
    N = int(input())
    S = list(input())
    Q = int(input())
    set_dic = {}

    for i, s in enumerate(S):
        if s not in set_dic:
            set_dic[s] = [i+1]
        else:
            bisect.insort_left(set_dic[s], i+1)

    anslist = []

    for _ in range(Q):
        query1, query2, query3 = input().split()
        if query1 == "1":
            i = int(query2)
            c = query3
            cap = S[i-1]
            if cap == c:
                continue
            set_dic[cap].remove(i)
            if c not in set_dic:
                set_dic[c] = [i]
            else:
                bisect.insort_left(set_dic[c], i)
            S[i-1] = c
        else:
            l = int(query2)
            r = int(query3)
            ansset = set()
            ans = 0
            for eachlist in set_dic.values():
                li = bisect.bisect_left(eachlist, l)
                ri = bisect.bisect_right(eachlist, r)
                if li != ri:
                    ans += 1
            anslist.append(ans)

    for i in anslist:
        print(i)

if __name__ == '__main__':
    solve()

Solution (Python):
import sys
input = sys.stdin.readline


class SegTree():
    
    def __init__(self, lists, function, basement):
        self.n = len(lists)
        self.K = (self.n-1).bit_length()
        self.f = function
        self.b = basement
        self.seg = [basement]*2**(self.K+1)
        X = 2**self.K
        for i, v in enumerate(lists):
            self.seg[i+X] = v
        for i in range(X-1, 0, -1):
            self.seg[i] = self.f(self.seg[i << 1], self.seg[i << 1 | 1])

    def update(self, k, value):
        X = 2**self.K
        k += X
        self.seg[k] = value
        while k:
            k = k >> 1
            self.seg[k] = self.f(self.seg[k << 1], self.seg[(k << 1) | 1])

    def query(self, L, R):
        num = 2**self.K
        L += num
        R += num
        vL = self.b
        vR = self.b
        while L < R:
            if L & 1:
                vL = self.f(vL, self.seg[L])
                L += 1
            if R & 1:
                R -= 1
                vR = self.f(self.seg[R], vR)
            L >>= 1
            R >>= 1
        return self.f(vL, vR)


def main():
    N = int(input())
    S = list(input())
    Q = int(input())
    que = [tuple(input().split()) for i in range(Q)]
    alpha = "abcdefghijklmnopqrstuvwxyz"
    Data = {alpha[i]: [0]*N for i in range(26)}
    for i in range(N):
        Data[S[i]][i] += 1
    SEG = {alpha[i]: SegTree(Data[alpha[i]], max, 0) for i in range(26)}
    for X, u, v in que:
        if X == "1":
            u = int(u)-1
            NOW = S[u]
            S[u] = v
            SEG[NOW].update(u, 0)
            SEG[v].update(u, 1)
        else:
            u, v = int(u)-1, int(v)-1
            res = 0
            for j in range(26):
                res += SEG[alpha[j]].query(u, v+1)
            print(res)


if __name__ == "__main__":
    main()

Solution (Python):
import sys


class SegTree():
    def __init__(self, lists, function, basement):
        self.n = len(lists)
        self.K = (self.n-1).bit_length()
        self.f = function
        self.b = basement
        self.seg = [basement]*2**(self.K+1)
        X = 2**self.K
        for i, v in enumerate(lists):
            self.seg[i+X-1] = v

        for i in range(2*X-2, 0, -2):
            self.seg[(i-1) >> 1] = self.f(self.seg[i], self.seg[i-1])

    def update(self, k, value):
        X = 2**self.K
        k += X-1
        self.seg[k] = value
        while k:
            k = (k-1) >> 1
            self.seg[k] = self.f(self.seg[(k << 1)+1], self.seg[(k << 1)+2])

    def query(self, L, R):
        num = 2**self.K-1
        L += num
        R += num
        vL = self.b
        vR = self.b
        while L < R:
            if L & 1 == 0:
                vL = self.f(vL, self.seg[L])
                L += 1
            if R & 1 == 0:
                R -= 1
                vR = self.f(self.seg[R], vR)
            L >>= 1
            R >>= 1
        return self.f(vL, vR)


input = sys.stdin.readline


def main():
    N = int(input())
    S = list(input())
    Q = int(input())
    que = [tuple(input().split()) for i in range(Q)]
    alpha = "abcdefghijklmnopqrstuvwxyz"
    Data = {alpha[i]: [0]*N for i in range(26)}
    for i in range(N):
        Data[S[i]][i] += 1
    SEG = {alpha[i]: SegTree(Data[alpha[i]], max, 0) for i in range(26)}
    for X, u, v in que:
        if X == "1":
            u = int(u)-1
            NOW = S[u]
            S[u] = v
            SEG[NOW].update(u, 0)
            SEG[v].update(u, 1)
        else:
            u, v = int(u)-1, int(v)-1
            res = 0
            for j in range(26):
                res += SEG[alpha[j]].query(u, v+1)
            print(res)


if __name__ == "__main__":
    main()

Solution (Python):
class SegTree():
    def __init__(self, lists, function, basement):
        self.n = len(lists)
        self.K = (self.n-1).bit_length()
        self.f = function
        self.b = basement
        self.seg = [basement]*2**(self.K+1)
        self.lazy_seg = [basement]*2**(self.K+1)
        X = 2**self.K
        for i, v in enumerate(lists):
            self.seg[i+X-1] = v

        for i in range(2*X-2, 0, -2):
            self.seg[(i-1) >> 1] = self.f(self.seg[i], self.seg[i-1])

    def update(self, k, value):
        
        X = 2**self.K
        k += X-1
        self.seg[k] = value
        while k:
            k = (k-1) >> 1
            self.seg[k] = self.f(self.seg[(k << 1)+1], self.seg[(k << 1)+2])


    def query(self, L, R):
        
        num = 2**self.K-1
        L += num
        R += num
        vL = self.b
        vR = self.b
        while L < R:
            if L & 1 == 0:
                vL = self.f(vL, self.seg[L])
                L += 1
            if R & 1 == 0:
                R -= 1
                vR = self.f(self.seg[R], vR)
            L >>= 1
            R >>= 1
        return self.f(vL, vR)

import sys
input=sys.stdin.readline
N=int(input())
S=list(input())
Q=int(input())
que=[tuple(input().split()) for i in range(Q)]
alpha="abcdefghijklmnopqrstuvwxyz"
Data={alpha[i]:[0]*N for i in range(26)}
for i in range(N):
    Data[S[i]][i]+=1
SEG={alpha[i]:SegTree(Data[alpha[i]],max,0) for i in range(26)}
for X,u,v in que:
    if X=="1":
        u=int(u)-1
        NOW=S[u]
        S[u]=v
        SEG[NOW].update(u,0)
        SEG[v].update(u,1)
    else:
        u,v=int(u)-1,int(v)-1
        res=0
        for j in range(26):
            res+=SEG[alpha[j]].query(u,v+1)
        print(res)

Solution (Python):
class SegTree():
    def __init__(self, lists, function, basement):
        self.n = len(lists)
        self.K = (self.n-1).bit_length()
        self.func = function
        self.basement = basement
        self.seg = [basement]*(2**(self.K+1))
        X=2**self.K
        for i,v in enumerate(lists):
            self.seg[i+X-1] = v

        for i in range(2*X-2, 0, -2):
            self.seg[(i-1)>>1] = self.func(self.seg[i], self.seg[i-1])

    def update(self, k, value):

        X=2**self.K
        k += X-1
        self.seg[k] = value
        while k:
            k = (k-1)>>1
            self.seg[k] = self.func(self.seg[(k<<1)+1], self.seg[(k<<1)+2])

            

    def query(self, p, q):
        if q <= p:
            return self.basement
        num = 2**self.K
        p += num-1
        q += num-2
        res = self.basement
        while q-p > 1:
            if p & 1 == 0:
                res = self.func(res, self.seg[p])
            if q & 1 == 1:
                res = self.func(res, self.seg[q])
                q -= 1
            p = p>>1
            q = (q-1)>>1
        if p == q:
            res = self.func(res, self.seg[p])
        else:
            res = self.func(self.func(res, self.seg[p]), self.seg[q])
        return res

import sys
input=sys.stdin.readline

N=int(input())
S=list(input())
Q=int(input())
que=[tuple(input().split()) for i in range(Q)]
alpha="abcdefghijklmnopqrstuvwxyz"
Data={alpha[i]:[0]*N for i in range(26)}
for i in range(N):
    Data[S[i]][i]+=1
SEG={alpha[i]:SegTree(Data[alpha[i]],max,0) for i in range(26)}
for X,u,v in que:
    if X=="1":
        u=int(u)-1
        NOW=S[u]
        S[u]=v
        SEG[NOW].update(u,0)
        SEG[v].update(u,1)
    else:
        u,v=int(u)-1,int(v)-1
        res=0
        for j in range(26):
            res+=SEG[alpha[j]].query(u,v+1)
        print(res)

Solution (Python):
class SegTree():
    def __init__(self, lists, function, basement):
        self.n = len(lists)
        self.K = (self.n-1).bit_length()
        self.func = function
        self.basement = basement
        self.seg = [basement]*2**(self.K+1)
        self.lazy_seg = [basement]*2**(self.K+1)
        X=2**self.K
        for i,v in enumerate(lists):
            self.seg[i+X-1] = v

        for i in range(2*X-2, 0, -2):
            self.seg[(i-1)>>1] = self.func(self.seg[i], self.seg[i-1])

    def update(self, k, value):
        
        X=2**self.K
        k += X-1
        self.seg[k] = value
        while k:
            k = (k-1)>>1
            self.seg[k] = self.func(self.seg[(k<<1)+1], self.seg[(k<<1)+2])

            

    def query(self, p, q):
        
        if q <= p:
            return self.basement
        num = 2**self.K
        p += num-1
        q += num-2
        res = self.basement
        while q-p > 1:
            if p & 1 == 0:
                res = self.func(res, self.seg[p])
            if q & 1 == 1:
                res = self.func(res, self.seg[q])
                q -= 1
            p = p>>1
            q = (q-1)>>1
        if p == q:
            res = self.func(res, self.seg[p])
        else:
            res = self.func(self.func(res, self.seg[p]), self.seg[q])
        return res

import sys
input=sys.stdin.readline
N=int(input())
S=list(input())
Q=int(input())
que=[tuple(input().split()) for i in range(Q)]
alpha="abcdefghijklmnopqrstuvwxyz"
Data={alpha[i]:[0]*N for i in range(26)}
for i in range(N):
    Data[S[i]][i]+=1
SEG={alpha[i]:SegTree(Data[alpha[i]],max,0) for i in range(26)}
for X,u,v in que:
    if X=="1":
        u=int(u)-1
        NOW=S[u]
        S[u]=v
        SEG[NOW].update(u,0)
        SEG[v].update(u,1)
    else:
        u,v=int(u)-1,int(v)-1
        res=0
        for j in range(26):
            res+=SEG[alpha[j]].query(u,v+1)
        print(res)

Solution (Python):


class SegTree():
    def __init__(self, lists, function, basement):
        self.n = len(lists)
        self.K = (self.n-1).bit_length()
        self.func = function
        self.basement = basement
        self.seg = [basement]*2**(self.K+1)

        for i in range(self.n):
            self.seg[i+2**self.K-1] = lists[i]

        for i in range(2**(self.K)-2, -1, -1):
            self.seg[i] = self.func(self.seg[2*i+1], self.seg[2*i+2])

    def update(self, k, value):
        
        k += 2**self.K-1
        self.seg[k] = value
        while k:
            k = (k-1)//2
            self.seg[k] = self.func(self.seg[k*2+1], self.seg[k*2+2])

    def query(self, p, q):
        
        if q <= p:
            return self.basement
        num = 2**self.K
        p += num-1
        q += num-2
        res = self.basement
        while q-p > 1:
            if p & 1 == 0:
                res = self.func(res, self.seg[p])
            if q & 1 == 1:
                res = self.func(res, self.seg[q])
                q -= 1
            p = p//2
            q = (q-1)//2
        if p == q:
            res = self.func(res, self.seg[p])
        else:
            res = self.func(self.func(res, self.seg[p]), self.seg[q])
        return res

import sys
input=sys.stdin.readline
N=int(input())
S=list(input())
Q=int(input())
que=[tuple(input().split()) for i in range(Q)]
alpha="abcdefghijklmnopqrstuvwxyz"
Data={alpha[i]:[0]*N for i in range(26)}
for i in range(N):
    Data[S[i]][i]+=1
SEG={alpha[i]:SegTree(Data[alpha[i]],max,0) for i in range(26)}
for X,u,v in que:
    if X=="1":
        u=int(u)-1
        NOW=S[u]
        S[u]=v
        SEG[NOW].update(u,0)
        SEG[v].update(u,1)
    else:
        u,v=int(u)-1,int(v)-1
        res=0
        for j in range(26):
            res+=SEG[alpha[j]].query(u,v+1)
        print(res)