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):
class SegmentTree():
    """A segment Tree.

    This is a segment tree without recursions.
    This can support queries as follows:
     - update a single value in O(logN).
     - get the folded value of values in a segment [l, r) in O(logN)
    N is the length of the given iterable value.

    Parameters
    ----------
    iterable : Iterable[_T]
        An iterable value which will be converted into a segment tree
    func : Callable[[_T, _T], _T]
        A binary function which returns the same type as given two.
        This has to satisfy the associative law:
            func(a, func(b, c)) = func(func(a, b), c)
    e : _T
        The identity element of the given func.
        In other words, this satisfies:
            func(x, e) = func(e, x) = x
    """
    
    def __init__(self, iterable, func, e):
        self.func = func
        self.e = e

        ls = list(iterable)
        self.n = 1 << len(ls).bit_length()
        ls.extend( [self.e] * (self.n - len(ls)) )

        self.data = [self.e] * self.n + ls
        for i in range(self.n-1, 0, -1):
            self.data[i] = self.func(self.data[2*i], self.data[2*i+1])

    def replace(self, index, value):
        """replace the old value of the given index with the given new value.

        This replaces the old value of the given index with the given new value in O(logN).
        This is like "list[index] = value".

        Parameters
        ----------
        index : int
            The index of the value which will be replaced.
        value : _T
            The new value with which the old value will be replaced.
        """
        index += self.n
        self.data[index] = value
        index //= 2
        while index > 0:
            self.data[index] = self.func(self.data[2*index], self.data[2*index+1])
            index //= 2
        
    def folded(self, l, r):
        """get the folded value of values in a segment [l, r).

        This get the folded value of values in a segment [l, r) in O(logN).
        If func is add, it returns the sum of values in [l, r).
        In other words, this is eqivalent to "sum(list[l:r])".
        If func is other functions, then this is equivalent to "accumulate(list[l:r], func)".

        Parameters
        ----------
        l : int
            The left edge.
        r : int
            The right edge.

        Returns
        -------
        _T(the same type as the type of the element of the given iterable)
            This is equivalent to func(list[l], func(list[l+1], ... ) ).
            If func is represented as '*', then it's:
            list[l] * list[l+1] * ... * list[r-1] 
        """

        left_folded = self.e
        right_folded = self.e
        l += self.n
        r += self.n
        while l < r:
            if l % 2:
                left_folded = self.func(left_folded, self.data[l])
                l += 1
            if r % 2:
                r -= 1
                right_folded = self.func(self.data[r], right_folded)
            l //= 2
            r //= 2
        
        return self.func(left_folded, right_folded)


from operator import or_

N = int(input())
S = input()

ls = [1 << (ord(c) - ord('a')) for c in S]
segtree = SegmentTree(ls, or_, 0)

Q = int(input())
for _ in range(Q):
    s = input()
    if s[0] == '1':
        i, c = s[2:].split()
        segtree.replace(int(i)-1, 1 << (ord(c) - ord('a')))
    else:
        l, r = map(int, s[2:].split())
        value = segtree.folded(l-1, r)
        print(format(value, 'b').count('1'))

Solution (Python):
import sys

input = lambda: sys.stdin.readline().rstrip()


class SegTree:

    def __init__(self, init_val, segfunc, ide_ele):

        n = len(init_val)
        self.ide_ele = ide_ele
        self.segfunc = segfunc
        self.num = 2**(n - 1).bit_length()
        self.seg = [self.ide_ele] * 2 * self.num

        for i in range(n):
            self.seg[i + self.num - 1] = init_val[i]

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

    def update(self, k, x):
        k += self.num - 1
        self.seg[k] = x
        while k:
            k = (k - 1) // 2
            self.seg[k] = self.segfunc(self.seg[k * 2 + 1], self.seg[k * 2 + 2])

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


def solve():

    N = int(input())
    S = list(input())
    Q = int(input())
    seg = [1 << (ord(s) - ord('a')) for s in S]

    segtree = []
    segfunc = lambda a, b: a | b

    segtree = SegTree(seg, segfunc, 0)

    ans = []
    for i in range(Q):
        a, b, c = input().split()
        a = int(a)

        if a == 1:
            b = int(b) - 1
            al = ord(c) - ord('a')
            segtree.update(b, 1 << al)
        elif a == 2:
            b, c = int(b) - 1, int(c)
            res = segtree.query(b, c)
            res = sum(list(map(int, bin(res)[2:])))
            ans.append(res)

    print('\n'.join(map(str, ans)))


if __name__ == '__main__':
    solve()

Solution (Python):
import sys

input = lambda: sys.stdin.readline().rstrip()


class SegTree:

    def __init__(self, init_val, segfunc, ide_ele):

        n = len(init_val)
        self.ide_ele = ide_ele
        self.segfunc = segfunc
        self.num = 2**(n - 1).bit_length()
        self.seg = [self.ide_ele] * 2 * self.num

        for i in range(n):
            self.seg[i + self.num - 1] = init_val[i]

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

    def update(self, k, x):
        k += self.num - 1
        self.seg[k] = x
        while k:
            k = (k - 1) // 2
            self.seg[k] = self.segfunc(self.seg[k * 2 + 1], self.seg[k * 2 + 2])

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


def solve():

    N = int(input())
    S = list(input())
    Q = int(input())
    seg = [[0 for _ in range(N)] for _ in range(26)]

    for i in range(N):
        al = ord(S[i]) - ord('a')
        seg[al][i] = 1

    segtree = []
    segfunc = lambda a, b: a | b

    for i in range(26):
        segtree.append(SegTree(seg[i], segfunc, 0))

    ans = []
    for i in range(Q):
        a, b, c = input().split()
        a = int(a)

        if a == 1:
            b = int(b) - 1
            ps = S[b]
            S[b] = c
            segtree[ord(ps) - ord('a')].update(b, 0)
            segtree[ord(c) - ord('a')].update(b, 1)
        elif a == 2:
            b, c = int(b) - 1, int(c)
            count = 0
            for i in range(26):
                count += segtree[i].query(b, c)
            ans.append(count)

    print('\n'.join(map(str, ans)))


if __name__ == '__main__':
    solve()

Solution (Python):
from bisect import bisect_left
import string 

dic={c:[] for c in string.ascii_lowercase}
N=int(input())
S=list(input())
Q=int(input())
for i in range(len(S)):
  dic[S[i]].append(i+1)

for i in range(Q):
  a,b,c=map(str,input().split())
  if a=='1':
    if S[int(b)-1]==c:
      continue
    b=int(b)
    f=S[b-1]
    d=bisect_left(dic[f],b)
    e=bisect_left(dic[c],b)
    dic[f].pop(d)
    dic[c].insert(e,b)
    S[b-1]=c
  else:
    ans=0
    b,c=int(b),int(c)
    for j in string.ascii_lowercase:
      d=bisect_left(dic[j],b)
      if d<len(dic[j]):
        if dic[j][d]<=c:
          ans+=1
    print(ans)

Solution (Python):
from bisect import bisect_left,bisect_right
import string 

dic = {c:[] for c in string.ascii_lowercase}

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

for i,c in enumerate(s,start=1):
  dic[c].append(i)
  
for i in range(q):
  p,l,r = map(str,input().split())
  if p =='1':
    j = int(l)
    if r == s[j-1]:
      continue
    c = s[j-1]    
    dic[c].pop(bisect_left(dic[c],j))
    dic[r].insert(bisect_left(dic[r],j),j)
    s[j-1] = r
  else:
    ans = 0
    l = int(l)
    r = int(r)
    for c in string.ascii_lowercase:
      pl = bisect_left(dic[c],l)
      if pl < len(dic[c]):
        if dic[c][pl] <= r:
          ans += 1
    print(ans)

Solution (Python):
from sys import stdin

class SegmentTree:
    
    
    
    def __init__(self, size, f=lambda x,y : x+y, default=0):
        self.size = 2**(size-1).bit_length() 
        self.default = default
        self.dat = [default]*(self.size*2) 
        self.f = f

    def update(self, i, x):
        i += self.size
        self.dat[i] = x
        while i > 0:
            i >>= 1
            self.dat[i] = self.f(self.dat[i*2], self.dat[i*2+1])

    def query(self, l, r):
        l += self.size
        r += self.size
        lres, rres = self.default, self.default
        while l < r:
            if l & 1:
                lres = self.f(lres, self.dat[l])
                l += 1

            if r & 1:
                r -= 1
                rres = self.f(self.dat[r], rres) 
            l >>= 1
            r >>= 1
        res = self.f(lres, rres)
        return res
def bc(x):
    return bin(x).count("1")

n = int(stdin.readline().rstrip())
s = stdin.readline().rstrip()
q = int(stdin.readline().rstrip())

lamb_or = lambda x,y : x|y
seg = SegmentTree(n,lamb_or,0)

for i,x in enumerate(s):
    seg.update(i,1 << ord(x)-97)

for _ in range(q):
    c,x,y = [x for x in stdin.readline().rstrip().split()]
    if c == '1':
        x = int(x)
        seg.update(x-1,1 << ord(y)-97)
    elif c == '2':
        x = int(x)
        y = int(y)
        print(bc(seg.query(x-1,y)))

Solution (Python):
n = int(input())
stmp = list(input())
Q = int(input())
target = ord("a")
s = [ord(stmp[i])-target for i in range(n)]

class BIT:
	"""
	<Attention> 0-indexed.
	query ... return the sum [0 to m]
	sum ... return the sum [a to b]
	sumall ... return the sum [all]
	add ... 'add' number to element (be careful that it doesn't set a value.)
	search ... the sum version of bisect.right
	output ... return the n-th element
	listout ... return the BIT list
	"""
	
	def query(self, m):
		res = 0
		while m > 0:
			res += self.bit[m]
			m -= m&(-m)
		return res
	
	def sum(self, a, b):
		return self.query(b)-self.query(a)
	
	def sumall(self):
		bitlen = self.bitlen-1
		return self.query(bitlen)
	
	def add(self, m, x):
		m += 1
		bitlen = len(self.bit)
		while m <= bitlen-1:
			self.bit[m] += x
			m += m&(-m)
		return
	
	def __init__(self, n):
		self.bitlen = n+1
		self.bit = [0]*(n+1)

b = [BIT(n) for i in range(26)]
for i in range(n):
	b[s[i]].add(i, 1)

for _ in range(Q):
	q,qtmpa,qtmpb = input().split()
	if q[0] == "1":
		qa = int(qtmpa)
		t = ord(qtmpb)-target
		b[t].add(qa-1, 1)
		b[s[qa-1]].add(qa-1, -1)
		s[qa-1] = t
	else:
		ans = 0
		qta = int(qtmpa)
		qtb = int(qtmpb)
		for i in range(26):
			if b[i].sum(qta-1, qtb) != 0:
				ans += 1
		print(ans)

Solution (Python):
class segtree:
    def __init__(self,N):
        self.n=(1<<len(bin(N-1)[2:]))
        self.x=[0 for _ in range(2*self.n)]
    def build(self,seq):
        for i, j in enumerate(seq, start=self.n):
            self.x[i]=1<<j
        for i in range(self.n-1, 0, -1):
            self.x[i]=self.x[i*2]|self.x[i*2+1]
    def update(self, i, c):
        j=i+self.n
        self.x[j]=1<<c
        while j>1:
            j//=2
            self.x[j]=self.x[j*2]|self.x[j*2+1]
    def get(self,l,r):
        ans=0
        l+=self.n
        r+=self.n
        while l<r:
            if l%2==1:
                ans|=self.x[l]
                l+=1
            if r%2==0:
                ans|=self.x[r]
                r-=1
            l//=2
            r//=2
        if l==r:
            ans|=self.x[l]
        cnt=sum(list(map(int, list(bin(ans)[2:]))))
        print(cnt)
        
n=int(input())
s=list(input())
s=[ord(i)-97 for i in s]
seg=segtree(n)
seg.build(s)

for _ in range(int(input())):
    que=list(input().split())
    if que[0]=='1':
        seg.update(int(que[1])-1, ord(que[2])-97)
    elif que[0]=='2':
        seg.get(int(que[1])-1,int(que[2])-1)

Solution (Python):
import sys
read=sys.stdin.readline
class SEGTree:
    def __init__(self,n):
        self.Unit=0
        i=1
        while(i<n):
            i*=2
        self.SEG=[self.Unit]*(2*i-1)
        self.d=i
    def update(self,i,x):
        i+=self.d-1
        self.SEG[i]=1<<x
        while i>0:
            i=(i-1)//2
            self.SEG[i]=self.SEG[i*2+1]|self.SEG[i*2+2]
    def find(self,a,b,k,l,r):
        if r<=a or b<=l:
            return self.Unit
        if a<=l and r<=b:
            return self.SEG[k]
        else:
            c1=self.find(a,b,2*k+1,l,(l+r)//2)
            c2=self.find(a,b,2*k+2,(l+r)//2,r)
            return c1|c2
    def get(self,a,b):
        return self.find(a,b,0,0,self.d)
def bitcnt(x):
    res=0
    while x>0:
        if x&1:
            res+=1
        x//=2
    return res

n=int(input())
s=input()
q=int(input())
seg=SEGTree(n)
for i in range(n):
    seg.update(i,ord(s[i])-97)
for i in range(q):
    q,x,y=read().rstrip().split()
    if q=='1':
        seg.update(int(x)-1,ord(y)-97)
    else:
        x,y=int(x)-1,int(y)
        bit=seg.get(x,y)
        print(bitcnt(bit))

Solution (Python):
import sys
sys.setrecursionlimit(10**7)

readline = sys.stdin.buffer.readline
def readstr():return readline().rstrip().decode()
def readstrs():return list(readline().decode().split())
def readint():return int(readline())
def readints():return list(map(int,readline().split()))
def printrows(x):print('\n'.join(map(str,x)))
def printline(x):print(' '.join(map(str,x)))


class AVL_like_BIT:  
    def __init__(self,n):  
        self.n = n
        self.tree = [0]*(self.n+1)
        self.depth = n.bit_length()

    def add(self,k):  
        while k<=self.n:
            self.tree[k]+=1
            k += k&-k
    
    def delete(self,k): 
        while k<=self.n:
            self.tree[k]-=1
            k += k&-k

    def sum(self,k):  
        ans = 0
        while k>0:
            ans += self.tree[k]
            k -= k&-k
        return ans
    
    def lower_bound(self,k):  
        x = self.sum(k-1)
        if x == self.sum(self.n):  
            return -1
        p = 0
        v = 1<<self.depth
        for i in range(self.depth + 1):  
            q = p+v
            if q <= self.n and self.tree[q] <= x:
                x -= self.tree[q]
                p += v
            v>>=1
        return p+1

    def upper_bound(self,k):  
        x = self.sum(k)
        if x == 0:  
            return -1
        p = 0
        v = 1<<self.depth
        for i in range(self.depth + 1):  
            q = p+v
            if q <= self.n and self.tree[q] < x:
                x -= self.tree[q]
                p += v
            v>>=1
        return p+1

    def query(self,k):  
        if k > self.sum(self.n):  
            return -1
        p = 0
        v = 1<<self.depth
        for i in range(self.depth + 1):  
            q = p+v
            if q <= self.n and self.tree[q] < k:
                k -= self.tree[q]
                p += v
            v>>=1
        return p+1

a = ord('a')

n = readint()
s = [0] + [ord(x)-a for x in readstr()]
q = readint()

avl = [AVL_like_BIT(5*10**5 + 10) for i in range(26)]
for i in range(1,n+1):
    avl[s[i]].add(i)

ans = []
for i in range(q):
    j,l,r = readstrs()
    j = int(j)
    l = int(l)
    if j==1:
        avl[s[l]].delete(l)
        s[l] = ord(r)-a
        avl[s[l]].add(l)
    else:
        r = int(r)
        ans.append(0)
        for k in range(26):
            if avl[k].sum(l-1)-avl[k].sum(r):
                ans[-1]+=1

printrows(ans)

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

def init():
    
    
    
    
    
    for j in range(26):
      for i in range(num-2,-1,-1) :
        seg[j][i]=max(seg[j][2*i+1],seg[j][2*i+2]) 
    
def update(k,x):
    K =k+num-1
    seg[SS[k]][K] = 0
    while K:
        K = (K-1)//2
        seg[SS[k]][K] = max(seg[SS[k]][K*2+1],seg[SS[k]][K*2+2])
    K =k+num-1
    seg[x][K]=1
    while K:
      K=(K-1)//2
      seg[x][K]=max(seg[x][K*2+1],seg[x][K*2+2])
    SS[k]=x
    
def query(p,q):
  a=0
  for i in range(26):
    P =p+ num-1
    Q =q+ num-1
    res=ide_ele
    while Q-P>1:
        if P&1 == 0:
            res = max(res,seg[i][P])
        if Q&1 == 1:
            res = max(res,seg[i][Q])
            Q -= 1
        P = P//2
        Q = (Q-1)//2
    if P == Q:
        res = max(res,seg[i][Q])
    else:
        res = max(max(res,seg[i][P]),seg[i][Q])
    a=a+res
  print(a)
  return a

n=int(input())
S=input()
q=int(input())



ide_ele = 0


num =2**(n-1).bit_length()
seg=[[ide_ele]*2*num for i in range(26)]


SS=[0]*num
for i in range(n):
  seg[ord(S[i])-97][i+num-1]=1
  SS[i]=ord(S[i])-97


init()


for xx in range(q):
  SSS=list(input().split())
  
  if SSS[0]=="1":
    
    update(int(SSS[1])-1,ord(SSS[2])-97)
  else:
    query(int(SSS[1])-1,int(SSS[2])-1)

Solution (Python):

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


ind=1
while 2**ind<=n:
    ind+=1
s+="*"*(2**ind-n)
seg=[]
seg2=[]

from collections import deque
tmp=deque([s])
while len(tmp)>0:
    t=tmp.popleft()
    cnt=0
    for ss in t:
        if ss!="*":
            cnt=cnt|2**(ord(ss)-97)
    seg.append(cnt)
    seg2.append(t)
    if len(t)>1:
        tmp.append(t[:len(t)//2])
        tmp.append(t[len(t)//2:])





q=int(input())

def change(i,s):
    
    
    
    global n,seg,ind
    ii=len(seg)-2**ind+i-1
    seg[ii]=2**(ord(s)-97)
    p=(ii-1)//2
    while 1:
        seg[p]=seg[2*p+1]|seg[2*p+2]
        if p==0:
            break
        p=(p-1)//2

    

from collections import deque


def count(l,r):
    global n,seg,s
    
    

    d = deque([(1,len(s),0)])
    ans=0

    while len(d)>0:
        tmp=d.popleft()
        
        ll,rr,i=tmp[0],tmp[1],tmp[2]
        if l<=ll and rr<=r:
            ans=ans|seg[i]
        elif (ll<=l and l<=rr) or (ll<=r and r<=rr):
            d.append((ll,ll+(rr-ll)//2,2*i+1))
            d.append((ll+(rr-ll)//2+1,rr,2*i+2))

    return str(bin(ans)).count("1")


result=[]


for _ in range(q):
    b,i,c=map(str,input().split())
    if b=="1":
        
        change(int(i),c)
    else:
        
        result.append(count(int(i),int(c)))

for item in result:
    print(item)

Solution (Python):
n = int(input())
S = input()
q = int(input())


class BIT:
    def __init__(self, n):
        """
        初期化
        Input:　
            n: 配列の大きさ
        """
        self.n = n
        self.bit = [0] * (n+10)

    def add(self, x, w):
        """
        更新クエリ(add)
        Input:
            x: インデックス
            w: 加える値
        Note:
            self.bitが更新される
        """        
        while x <= self.n:
            self.bit[x] += w
            x += x&-x
    
    def sum(self, x):
        """
        部分和算出クエリ
        Input:
            x: インデックス
        Return:
            [1,a]の部分和
        """
        cnt = 0
        while x > 0:
            cnt += self.bit[x]
            
            x -= x&-x
        return cnt   
    
    def psum(self, a, b):
        """
        区間[a,b)(0-indexed)における和
        Input
            a,b: 半開区間
        Return
            [a,b)の和
        """
        return self.sum(b-1) - self.sum(a-1)


def str2num(s):
    return ord(s)-ord("a")

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

ans = []
for i, s in enumerate(S):
    ind = str2num(s)
    bits[ind].add(i+1, 1)

S = list(S)
for _ in range(q):
    x,a,b = input().split()
    if x == "1":
        i = int(a)
        
        ind_before = str2num(S[i-1])
        ind = str2num(b)
        bits[ind_before].add(i,-1)
        bits[ind].add(i, 1)
        S[i-1] = b
    else:
        l = int(a)
        r = int(b)
        cnt = 0
        for bit in bits:
            if bit.psum(l,r+1) > 0:
                cnt += 1
        ans.append(cnt)
print(*ans)

Solution (Python):
import bisect
import sys
sys.setrecursionlimit(10**9)

def main():
    N = int(input())
    S = list(input())

    a_ord = ord('a')
    z_ord = ord('z')

    set_list = [[] for _ in range(z_ord+1)]
    for i in range(N):
        s = S[i]
        set_list[ord(s)].append(i)

    Q = int(input())
    for q in range(Q):
        ipt = input().split()
        if ipt[0] == "1":
            i,c = int(ipt[1]), ipt[2]
            j = ord(S[i-1])

            if j == ord(c): continue
            set_list[j].remove(i-1)
            bisect.insort_left(set_list[ord(c)],i-1)
            S[i-1] = c
            

        else:
            l,r = int(ipt[1]), int(ipt[2])
            ans = 0
            
            
            

            for i in range(a_ord,z_ord+1):
                st = set_list[i]
                if not len(st) > 0: continue

                
                l_p = bisect.bisect_left(st,l-1)
                r_p = bisect.bisect_right(st,r-1)

                
                if l_p < r_p:
                    ans += 1

            
            print(ans)



if __name__ == "__main__":
  main()

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

    ordA = ord('a')

    N = int(input())
    Ss = input().strip()
    nos = [ord(S)-ordA for S in Ss]
    Q = int(input())

    idEle = 0
    def _binOpe(x, y):
        return x | y
    def makeSegTree(numEle):
        numPow2 = 2 ** (numEle-1).bit_length()
        data = [idEle] * (2*numPow2)
        return data, numPow2
    def setInit(As):
        for iST, A in enumerate(As, numPow2):
            data[iST] = A
        for iST in reversed(range(1, numPow2)):
            data[iST] = _binOpe(data[2*iST], data[2*iST+1])
    def _update1(iA, A):
        iST = iA + numPow2
        data[iST] = A
    def update(iA, A):
        _update1(iA, A)
        iST = iA + numPow2
        while iST > 1:
            iST >>= 1
            data[iST] = _binOpe(data[2*iST], data[2*iST+1])
    def getValue(iSt, iEn):
        L = iSt + numPow2
        R = iEn + numPow2
        ans = idEle
        while L < R:
            if L & 1:
                ans = _binOpe(ans, data[L])
                L += 1
            if R & 1:
                R -= 1
                ans = _binOpe(ans, data[R])
            L >>= 1
            R >>= 1
        return ans

    data, numPow2 = makeSegTree(N)

    As = [(1<<no) for no in nos]
    setInit(As)

    anss = []
    for _ in range(Q):
        tp, v1, v2 = input().split()
        if tp == '1':
            pos = int(v1)-1
            c = ord(v2)-ordA
            update(pos, 1<<c)
        else:
            L, R = int(v1)-1, int(v2)-1
            v = getValue(L, R+1)
            ans = bin(v).count('1')
            anss.append(ans)

    print('\n'.join(map(str, anss)))


solve()

Solution (Python):
import sys
input=sys.stdin.buffer.readline
sys.setrecursionlimit(10**9)
class SegmentTree:
    
    
    __slots__=["size","func","default_val","tree","first_idx"]
    def __init__(self,initial_value_list,func,default_val,first_index=0):
        n=len(initial_value_list)
        self.first_idx=first_index
        self.size=1<<(n-1).bit_length()
        self.func=func
        self.default_val=default_val
        self.tree=[default_val for i in range(2*self.size)]
        
        for i in range(n):
            d=[0]*26;d[initial_value_list[i]-97]=1
            self.tree[self.size+i]=d
        for i in range(self.size-1,0,-1):
            self.tree[i]=self.func(self.tree[2*i],self.tree[2*i+1])

    def update(self,k,x):
        k+=self.size-self.first_idx
        self.tree[k]=x
        while k>1:
            k>>=1
            self.tree[k]=self.func(self.tree[2*k],self.tree[2*k+1])
    def query(self, l, r):
        l+=self.size-self.first_idx
        r+=self.size-self.first_idx
        lret,rret=self.default_val,self.default_val
        while l<r:
            if l&1:
                lret=self.func(lret,self.tree[l])
                l+=1
            if r&1:
                r-=1
                rret=self.func(self.tree[r], rret) 
            l>>=1
            r>>=1
        return self.func(lret, rret)
n=int(input())
def add(x,y):
    v=[0]*26
    for i in range(26):
        v[i]=x[i]+y[i]
    return v
seg=SegmentTree(list(input().rstrip()),add,[0]*26,1)
q=int(input())

for i in range(q):
    a,s,d=input().split()
    if int(a)==1:
        s=int(s)
        v=[0]*26;v[int.from_bytes(d,'big')-97]+=1
        seg.update(s,v)
        
    else:
        r=seg.query(1,int(s))
        l=seg.query(1,int(d)+1)
        
        ans=0
        for i in range(26):
            if l[i]>r[i]:ans+=1
        print(ans)

Solution (Python):
import sys
def input(): return sys.stdin.readline().rstrip()
def ctoi(c):
    return ord(c)-97
class BIT:
    def __init__(self, n):
        self.unit_sum=0 
        self.n=n
        self.dat=[0]*(n+1)
    def add(self,a,x): 
        i=a
        while i<=self.n:
            self.dat[i]+=x
            i+=i&-i
    def sum(self,a,b=None): 
        if b!=None:
            return self.sum(b-1)-self.sum(a-1) 
        res=self.unit_sum
        i=a
        while i>0:
            res+=self.dat[i]
            i-=i&-i
        return res  
    def __str__(self):
        self.ans=[]
        for i in range(1,self.n):
            self.ans.append(self.sum(i,i+1))
        return ' '.join(map(str,self.ans))

def main():
    n=int(input())
    S=list(input())
    q=int(input())
    BIT_tree=[]
    for i in range(26):
        obj=BIT(n+1)
        BIT_tree.append(obj)
    for i in range(n):
        BIT_tree[ctoi(S[i])].add(i+1,1)
    for _ in range(q):
        query=input().split()
        if query[0]=="1":
            index,x=int(query[1])-1,query[2]
            BIT_tree[ctoi(S[index])].add(index+1,-1)
            BIT_tree[ctoi(x)].add(index+1,1)
            S[index]=x
        else:
            l,r=int(query[1])-1,int(query[2])-1
            ans=0
            for c in range(26):
                if BIT_tree[c].sum(l+1,r+2):
                    ans+=1
            print(ans)

if __name__=='__main__':
    main()

Solution (Python):
import sys
def input(): return sys.stdin.readline().rstrip()
from bisect import bisect_left,bisect
def main():
    n=int(input())
    S=list(input())
    q=int(input())
    set_s={chr(ord('a')+i):[] for i in range(26)}
    for i,s in enumerate(S):
        set_s[s].append(i)
    for _ in range(q):
        query=input().split()
        if query[0]=="1":
            i,c=int(query[1])-1,query[2]
            if S[i]==c:continue
            set_s[S[i]].remove(i)
            set_s[c].insert(bisect_left(set_s[c],i),i)
            S[i]=c
        else:
            l,r=int(query[1])-1,int(query[2])-1
            ans=0
            for i in range(26):
                ss=chr(ord('a')+i)
                if bisect(set_s[ss],r)>bisect_left(set_s[ss],l):
                    ans+=1
            print(ans)


if __name__=='__main__':
    main()