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):
from bisect import bisect_left

n = int(input())
s = list(input())
q = int(input())
query = [input() for _ in range(q)]

p = [[] for _ in range(26)]

for i, x in enumerate(s):
    p[ord(x) - ord('a')].append(i)

for x in query:
    a, b, c = x.split()
    
    if a == '1':
        b = int(b) - 1
        if s[b] == c:
            continue
        d = ord(s[b]) - ord('a')
        e = ord(c) - ord('a')
        temp = bisect_left(p[d], b)
        p[d].pop(temp)
        temp = bisect_left(p[e], b)
        p[e].insert(temp, b)
        s[b] = c
    else:
        b = int(b) - 1
        c = int(c) - 1
        
        ans = 0
        for i in range(26):
            L = bisect_left(p[i], b)
            if L >= len(p[i]):
                continue
            if p[i][L] <= c:
                ans += 1
        print(ans)

Solution (Python):
al=list('abcdefghijklmnopqrstuvwxyz')

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

def init(init_val):
    
    for i in range(n):
        seg[i+num-1]=1<<al.index(init_val[i])
    
    for i in range(num-2,-1,-1):
        seg[i]=segfunc(seg[2*i+1],seg[2*i+2])
    
def update(k,x):
    k+=num-1
    seg[k]=x
    while k+1:
        k=(k-1)//2
        seg[k]=segfunc(seg[k*2+1],seg[k*2+2])

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

ide_ele=0
n=int(input())
num=2**(n-1).bit_length()
seg=[ide_ele]*2*num
a=list(input())
init(a)
ans=0
q=int(input())

for i in range(q):
    p=list(map(str,input().split()))
    if p[0]=='1':
        update(int(p[1])-1,1<<al.index(p[2]))
    else:
        print(query(int(p[1])-1,int(p[2])))

Solution (Python):
import sys
input = sys.stdin.readline
n = int(input())
s = list(str(input().rstrip()))
q = int(input())


class SSQ:
    def __init__(self, n, e):
        
        self.e = e
        
        self.num_min = 2**(n-1).bit_length()
        self.seg_min = [self.e]*2*self.num_min

    def update(self, k, x):
        k += self.num_min-1
        self.seg_min[k] = x
        while k:
            k = (k-1)//2
            self.seg_min[k] = self.seg_min[k*2+1] or self.seg_min[k*2+2]

    def query(self, p, q):
        q += 1
        if q <= p:
            return self.e
        p += self.num_min-1
        q += self.num_min-2
        res = self.e
        while q-p > 1:
            if p & 1 == 0:
                res = res or self.seg_min[p]
            if q & 1 == 1:
                res = res or self.seg_min[q]
                q -= 1
            p = p//2
            q = (q-1)//2
        if p == q:
            res = res or self.seg_min[p]
        else:
            res = res or self.seg_min[p] or self.seg_min[q]
        return res

ssqs = [SSQ(n, False) for i in range(26)]

for i in range(n):
    ssqs[ord(s[i]) - ord('a')].update(i, True)

out = []
for i in range(q):
    com, x, y = list(input().split())
    if com == '1':
        idx = int(x) - 1
        pre_alph = ord(s[idx]) - ord('a')
        ssqs[pre_alph].update(idx, False)
        s[idx] = y
        alph = ord(y) - ord('a')
        ssqs[alph].update(idx, True)
    else:
        x, y = int(x) - 1, int(y) - 1
        cnt = 0
        for i in range(26):
            cnt += 1 if ssqs[i].query(x, y) else 0
        out.append(str(cnt))
print("\n".join(out))

Solution (Python):
al=list('abcdefghijklmnopqrstuvwxyz')

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

def init(init_val):
    
    for i in range(n):
        seg[i+num-1]=1<<al.index(init_val[i])
    
    for i in range(num-2,-1,-1):
        seg[i]=segfunc(seg[2*i+1],seg[2*i+2])
    
def update(k,x):
    k+=num-1
    seg[k]=x
    while k+1:
        k=(k-1)//2
        seg[k]=segfunc(seg[k*2+1],seg[k*2+2])

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

ide_ele=0
n=int(input())
num=2**(n-1).bit_length()
seg=[ide_ele]*2*num
a=list(input())
init(a)
ans=0
q=int(input())

for i in range(q):
    p=list(map(str,input().split()))
    if p[0]=='1':
        update(int(p[1])-1,1<<al.index(p[2]))
    else:
        print(query(int(p[1])-1,int(p[2])))

Solution (Python):

import sys

sys.setrecursionlimit(300000)



def update(i, val, n, bi_tree, sign=1):
    i += 1
    while i < n:
        bi_tree[i][val] += (1 * sign)
        i += i & -i


def get_sum(i, bi_tree):
    ans = [0] * 26
    while i > 0:
        tmp = bi_tree[i]
        for j in range(26):
            ans[j] += tmp[j]
        i -= i & -i
    return ans


def get_range_sum(left, right, bi_tree):
    r_sum = get_sum(right, bi_tree)
    l_sum = get_sum(left - 1, bi_tree)
    for i in range(26):
        r_sum[i] -= l_sum[i]
    return r_sum


from pprint import pprint

def solve(N, S, Q, queries):
    
    
    bit = [[0] * 26 for i in range(N + 1)]
    s = []
    for i, c in enumerate(S):
        if 'a' <= c <= 'z':
            update(i, ord(c) - ord('a'), N + 1, bit)
        s.append(c)

    for q in queries:
        if q[0] == '1':
            i, c = int(q[1]) - 1, q[2]
            p = s[i]
            update(i, ord(p) - ord('a'), N + 1, bit, -1)
            update(i, ord(c) - ord('a'), N + 1, bit, 1)
            s[i] = c
        if q[0] == '2':
            l, r = int(q[1]), int(q[2])
            counts = get_range_sum(l, r, bit)
            ret = 0
            for x in counts:
                if x > 0:
                    ret += 1
            print(ret)
        
        
        

    return


def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    N = int(next(tokens))
    S = str(next(tokens))
    Q = int(next(tokens))
    q = []
    for i in range(Q):
        q.append(list(map(str, input().split())))
    solve(N, S, Q, q)

if __name__ == '__main__':
    main()

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


def init(n, s):
    num = len(str(bin(n-1))) -2
    seg = [0] * (2**(num+1))
    seg_num = 2**num

    for i in range(n):
        tmp = ord(s[i]) - 97
        seg[i + seg_num] = 1 << tmp

    for i in range(seg_num-1, 0, -1):
        seg[i] = seg[i*2] | seg[i*2+1]

    return seg, seg_num

def calc_sum(head, tail):
    head += seg_num
    tail += seg_num
    l = []
    while(head <= tail):
        if(head == tail):
            l.append(head)
            break

        if(head % 2 == 1):
            l.append(head)
            head += 1
        head = head //2

        if(tail % 2 == 0):
            l.append(tail)
            tail -= 1
        tail = tail //2

    ans = 0
    for i in l:
        ans = ans | seg[i]
    ans = str(bin(ans)).count('1')
    return(ans)

def update(i,s):
    i += seg_num
    tmp = ord(s) - 97
    seg[i] = 1 << tmp
    while(i > 1):
        i = i//2
        seg[i] = seg[2*i] | seg[2*i+1]

seg,seg_num = init(n,s)

for i in range(q):
    q1,q2,q3 = input().split()
    if(q1 =='1'):
        update(int(q2)-1, q3)
    else:
        q2,q3 = int(q2),int(q3)
        print(calc_sum(q2-1, q3-1))

Solution (Python):
n=int(input())
ss=input()
dps=['a']*n
from collections import defaultdict
d=defaultdict(list)
for i in range(n):
    d[ss[i]].append(i)
    dps[i]=ss[i]
sorted(d.items())

Q=int(input())
import bisect
for i in range(Q):
    num,ii,c=input().split()
    
    if num=='1':
        if c==dps[int(ii)-1]:
            continue
        bisect.insort_left(d[c],int(ii)-1)
        d[dps[int(ii)-1]].remove(int(ii)-1)
        dps[int(ii)-1]=c
    else:
        l,r=int(ii)-1,int(c)-1
        count=0
        for k,lst in d.items():
            idx=bisect.bisect_left(lst,l)
            idx1=bisect.bisect_right(lst,r)
            count+=((idx1-idx)>0)
            
        print(count)
        pass

Solution (Python):
import sys
sys.setrecursionlimit(10**9)
input = sys.stdin.readline


class SegmentTree():
    def __init__(self, n):
        self.n = 2**(n-1).bit_length()
        self.data = [0 for _ in range(2*self.n)]

    def set(self, k, v):
        v_val = ord(v)-ord('a') 
        self.data[k+self.n-1] = 1 << v_val 

    def build(self):
        for k in reversed(range(self.n-1)):
            self.data[k] = self.data[k*2+1] | self.data[k*2+2] 

    def update(self, k, a):
        k += self.n-1
        v_val = ord(a)-ord("a")
        self.data[k] = 1 << v_val

        while k > 0:
            k = (k-1)//2
            self.data[k] = self.data[k*2+1] | self.data[k*2+2]

    def query(self, l, r):
        L = l+self.n
        R = r+self.n
        ret = 0
        while L < R:
            if R & 1:
                R -= 1
                ret |= self.data[R-1]
            if L & 1:
                ret |= self.data[L-1]
                L += 1
            L >>= 1
            R >>= 1
        return ret

N = int(input())
S = [v for v in input()[:-1]]
Q = int(input())
query = [[v for v in input()[:-1].split()] for _ in range(Q)]

Seg = SegmentTree(N)
for i, s in enumerate(S):
    Seg.set(i, s)

Seg.build()

for q, v1, v2 in query:
    if q == "1":
        Seg.update(int(v1)-1, v2)
    else:
        val = Seg.query(int(v1)-1, int(v2))
        print(bin(val)[2:].count("1"))

Solution (Python):
from bisect import bisect_left, bisect_right
N = int(input())
S = list(input())
Q = int(input())

D = {chr(ord('a') + i): [] for i in range(26)}

for i, s in enumerate(S):
    D[s].append(i)

for q in range(Q):
    query = list(input().split())
    if query[0] == '1':
        i, x = int(query[1]), query[2]
        i -= 1
        s = S[i]
        if s == x:
            continue

        D[s].remove(i)
        next_i = bisect_left(D[x], i)
        D[x].insert(next_i, i)
        S[i] = x

    if query[0] == '2':
        l, r = int(query[1]), int(query[2])
        l, r = l - 1, r - 1
        ans = 0
        for i in range(26):
            s = chr(ord('a') + i)

            li = bisect_left(D[s], l)
            ri = bisect_right(D[s], r)

            if ri - li > 0:
                ans += 1

        print(ans)

Solution (Python):
N = int(input())
A = [ord(a) - 97 for a in input()]
NN = 19
BIT=[[0]*(2**NN+1) for _ in range(26)]
 
def addbit(t, i, x):
    while i <= 2**NN:
        BIT[t][i] += x
        i += i & (-i)

def getsum(t, i):
    ret = 0
    while i != 0:
        ret += BIT[t][i]
        i -= i&(-i)
    return ret

for i, a in enumerate(A):
    BIT[a][i+1] += 1

for t in range(26):
    B = [0] * (2**NN+1)
    for i in range(1<<NN):
        B[i+1] = B[i] + BIT[t][i]
    for i in range(1<<NN):
        BIT[t][i] = B[i] - B[i - (i & (-i))]

Q = int(input())
for _ in range(Q):
    a, b, c = input().rstrip().split()
    if a == "1":
        b = int(b)
        c = ord(c) - 97
        t = A[b-1]
        addbit(t, b+1, -1)
        addbit(c, b+1, 1)
        A[b-1] = c
    else:
        b, c = int(b), int(c)
        s = 0
        for t in range(26):
            s += 1 if getsum(t, c+1) - getsum(t, b) else 0
        print(s)

Solution (Python):

from collections import defaultdict
INF = float("inf")

def getlist():
	return list(map(int, input().split()))


def update(data, k, x, N0):
	k += N0 - 1
	data[k] = x
	while k > 0:
		k = (k - 1) // 2
		data[k] = data[2 * k + 1] | data[2 * k + 2]


def query(data, a, b, k, l, r):
	if r <= a or b <= l:
		return 0
	if a <= l and r <= b:
		return data[k]
	else:
		vl = query(data, a, b, k * 2 + 1, l, (l + r) // 2)
		vr = query(data, a, b, k * 2 + 2, (l + r) // 2, r)
		return vl | vr


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

	
	N0 = 2 ** (N - 1).bit_length()
	S = list(input())
	data = [0] * (2 * N0 - 1)
	for i in range(N):
		data[N0 - 1 + i] = 2 ** (ord(S[i]) - 97)
		ind = N0 - 1 + i
		while ind > 0:
			ind = (ind - 1) // 2
			data[ind] = data[ind * 2 + 1] | data[ind * 2 + 2]

	Q = int(input())
	for _ in range(Q):
		que = list(input().split())
		if que[0] == "1":
			i = int(que[1]) - 1
			c = 2 ** (ord(que[2]) - 97)
			update(data, i, c, N0)
		else:
			a = int(que[1])
			b = int(que[2])
			a -= 1
			jjj = query(data, a, b, 0, 0, N0)
			ans = 0
			while jjj != 0:
				if jjj % 2 == 1:
					ans += 1
				jjj = int(jjj // 2)

			print(ans)


if __name__ == '__main__':
	main()

Solution (Python):
def main():
  import sys
  input = sys.stdin.readline
  n = int(input())
  s = list(input())

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

  def init(init_val):
      
      for i in range(n):
          seg[i+num-1]=init_val[i]    
      
      for i in range(num-2,-1,-1) :
          seg[i]=segfunc(seg[2*i+1],seg[2*i+2]) 
      
  def update(k,x):
      k += num-1
      seg[k] = x
      while k:
          k = (k-1)//2
          seg[k] = segfunc(seg[k*2+1],seg[k*2+2])
      
  def query(p,q):
      if q<=p:
          return ide_ele
      p += num-1
      q += num-2
      res=ide_ele
      while q-p>1:
          if p&1 == 0:
              res = segfunc(res,seg[p])
          if q&1 == 1:
              res = segfunc(res,seg[q])
              q -= 1
          p = p//2
          q = (q-1)//2
      if p == q:
          res = segfunc(res,seg[p])
      else:
          res = segfunc(segfunc(res,seg[p]),seg[q])
      return res

  
  ide_ele = 0

  
  num =2**(n-1).bit_length()
  seg=[ide_ele]*2*num

  A = []
  for i in range(n):
    A.append(1<<(ord(s[i])-96))
  init(A)
  q = int(input())
  for _ in range(q):
    p,a,b = input().split()
    if p == "1":
      update(int(a)-1,1<<(ord(b)-96))
    if p == "2":
      print(bin(query(int(a)-1,int(b))).count("1"))
main()

Solution (Python):
N = int(input())
S = list(input())
Q = int(input())
query = [input().split() for _ in range(Q)]

bit = [[0 for _ in range(26)] for _ in range(N + 1)]



def bit_add(i, s):
    ss = ord(s) - ord("a")
    while i <= N:
        bit[i][ss] += 1
        i += i & - i
def bit_add2(i, s):
    ss = ord(s) - ord("a")
    while i <= N:
        bit[i][ss] += -1
        i += i & - i
        
def bit_sum(i):
    s = [0] * 26
    while i:
        for j in range(26):
            s[j] += bit[i][j]
        i -= i & -i
    return s
for i in range(1, N + 1):
    s = S[i - 1]
    bit_add(i, s)



for x, y, z in query:
    if x == "1":
        y = int(y)
        bit_add2(y, S[y - 1])
        bit_add(y, z)
        S[y - 1] = z
    if x == "2":
        answer = 0
        y, z = int(y) - 1, int(z)
        yy = bit_sum(y)
        zz = bit_sum(z)
        
        
        for i in range(26):
            if zz[i] - yy[i] > 0:
                answer += 1
        print(answer)

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

def I(): return int(input())
def MI(): return map(int, input().split())
def LI(): return list(map(int, input().split()))



def main():
    mod=10**9+7
    N=I()
    S=input()
    Q=I()
    
    

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


    
    def init(init_val):
        
        for i in range(N):
            seg[i+num-1]=set([ord(init_val[i])])    
        
        for i in range(num-2,-1,-1) :
            seg[i]=segfunc(seg[2*i+1],seg[2*i+2]) 
            

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

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


    
    ide_ele = set([])

     
    num =2**(N-1).bit_length()
    seg=[ide_ele]*2*num
    init(S)



    
    for i in range(Q):
        q,a,b=input().split()
        if q=="1":
            update(int(a)-1,set([ord(b)]))
        else:
            print(query(int(a)-1,int(b)))
            
    
    

main()

Solution (Python):
import sys
input = sys.stdin.readline
class Bit:
    def __init__(self, n):
        self.size = n
        self.tree = [0] * (n + 1)
 
    def sum(self, i):
        if i == 0:
            return 0
        s = 0
        while i > 0:
            s += self.tree[i]
            i -= i & -i
        return s
 
    def add(self, i, x):
        while i <= self.size:
            self.tree[i] += x
            i += i & -i
aas = "abcdefghijklmnopqrstuvwxyz"
N = int(input().strip())
S = list(input().strip())
Q = int(input().strip())
cbt = dict()
MX = 5 * 10**5 + 2
for c in aas:
    cbt[c] = Bit(MX)
    for i, a in enumerate(S):
        if a == c:
            cbt[c].add(i+1, 1)

for _ in range(Q):
    t, i, c = input().split()
    t = int(t)
    if t == 1:
        i = int(i)
        if S[i-1] != c:
            cbt[S[i-1]].add(i, -1)
            cbt[c].add(i, 1)
            S[i-1] = c
    else:

        l, r = int(i), int(c)

        s = 0
        for a in aas:
            bt = cbt[a]

            s += (bt.sum(r)-bt.sum(l-1)>0)
        print(s)

Solution (Python):

import sys
INF = float("inf")

import math


class SegmentTree(object):
    

    def __init__(self, N):
        """サイズNの配列を元にしたセグメント木
        """
        
        self.idelem = 0
        

        def f(a, b):
            return a | b

        self.func = f

        self.N0 = 1
        while self.N0 < N:
            self.N0 <<= 1
        self.tree = [self.idelem]*(2*self.N0)

    def update(self, k, x):
        """k番目の値をxに更新
        """
        k += self.N0-1
        self.tree[k] = x
        while k > 1:
            k = (k-1)//2
            self.tree[k] = self.func(self.tree[2*k+1], self.tree[2*k+2])

    def query(self, l, r):
        """区間[l, r)の最小値
        """
        l += self.N0-1
        r += self.N0-1
        s = self.idelem
        while l < r:
            if r % 2 == 0:
                r -= 1
                s = self.func(s, self.tree[r])

            if l % 2 == 0:
                s = self.func(s, self.tree[l])
                l += 1
            l //= 2
            r //= 2
        return s

    def __str__(self):
        return str(self.tree[self.N0-1:-1])


def bit_sum(n):
    wa = 0
    while n > 0:
        wa += n & 1
        n >>= 1
    return wa


def main():
    N = int(input())
    S = input()
    Q = int(input())
    query = [input().split() for i in range(Q)]

    seg = SegmentTree(N)
    for i, c in enumerate(S):
        seg.update(i, 1 << (ord(c)-ord('a')))

    for q in query:
        if q[0] == "1":
            seg.update(int(q[1])-1, 1 << (ord(q[2])-ord('a')))
        else:
            ans = seg.query(int(q[1])-1, int(q[2]))
            print(bit_sum(ans))
    pass


if __name__ == '__main__':
    main()

Solution (Python):
N = int(input())
S = [ord(i) - 97 for i in input()]
Q = int(input())


class BinaryIndexedTree() :
  def __init__(self, N) :
    self.size = N
    self.tree = [0] * (N + 1)
      
  def sum(self, i) :
    s = 0
    while i > 0 :
      s += self.tree[i]
      i -= i & -i
    return s
      
  def add(self, i, x) :
    while i <= self.size :
      self.tree[i] += x
      i += i & -i
      
alph = [BinaryIndexedTree(N + 10) for _ in range(26)]
for i in range(N) :
  alph[S[i]].add(i + 1, 1)

for _ in range(Q) :
  type, x, y = input().split()
  if type == '1' :
    x = int(x)
    s = S[x - 1]
    alph[s].add(x, -1)
    alph[ord(y) - 97].add(x, 1)
    S[x - 1] = ord(y) - 97
  else :
    x, y = int(x), int(y)
    ret = 0
    for i in range(26) :
      if alph[i].sum(y) - alph[i].sum(x - 1) > 0 :
        ret += 1
    print(ret)

Solution (Python):
def segfunc(x,y):
    return x | y

def init(init_val):
    
    for i in range(n):
        seg[i+num-1]=init_val[i]    
    
    for i in range(num-2,-1,-1) :
        seg[i]=segfunc(seg[2*i+1],seg[2*i+2]) 
    
def update(k,x):
    k += num-1
    seg[k] = x
    while k:
        k = (k-1)//2
        seg[k] = segfunc(seg[k*2+1],seg[k*2+2])
    
def query(p,q):
    if q<=p:
        return ide_ele
    p += num-1
    q += num-2
    res=ide_ele
    while q-p>1:
        if p&1 == 0:
            res = segfunc(res,seg[p])
        if q&1 == 1:
            res = segfunc(res,seg[q])
            q -= 1
        p = p//2
        q = (q-1)//2
    if p == q:
        res = segfunc(res,seg[p])
    else:
        res = segfunc(segfunc(res,seg[p]),seg[q])
    return res

ide_ele = 0

n = 500000
num =2**(n-1).bit_length()
seg=[ide_ele]*2*num
def main():
    N = int(input())
    S = input()
    for i, s in enumerate(S):
        update(i, 1 << (ord(s) - 97))
        
    Q = int(input())
    for _ in range(Q):
        t, a, b = input().split()
        if t == '1':
            update(int(a) - 1, 1 << (ord(b) - 97))
        else:
            print(bin(query(int(a) - 1, int(b))).count('1'))

main()

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

D=[[0]*26 for _ in range(n+1)]
for i,s in enumerate(S):
  for j in range(26):
    if j==ord(s)-97:
      D[i+1][j]=D[i][j]+1
    else:
      D[i+1][j]=D[i][j]

n_max=n+1
nn=n_max.bit_length()+1
BITS=[[0]*(2**nn) for _ in range(26)]
for i in range(26):
  BITS[i].insert(0,0)

def bitsum(BIT,i):
  s=0
  while i>0:
    s+=BIT[i]
    i-=i&(-i)
  return s

def bitadd(BIT,i,x):
  while i<=2**nn:
    BIT[i]+=x
    i+=i&(-i)
  return BIT

for _ in range(q):
  q1,q2,q3=map(str,input().split())
  if q1=="1":
    num=int(q2)-1
    prev=ord(S[num])-97
    new=ord(q3)-97
    S[num]=q3
    if prev!=new:
      bitadd(BITS[prev],num+1,-1)
      bitadd(BITS[new],num+1,1)
  else:
    l,r=int(q2),int(q3)
    ans=0
    for i in range(26):
      diff=D[r][i]-D[l-1][i]+bitsum(BITS[i],r)-bitsum(BITS[i],l-1)
      if diff>0:
        ans+=1
    print(ans)

Solution (Python):
import sys

class RMQ(): 
    def __init__(self, N, V): 
        d, k = 1, 0
        while d < N:
            d <<= 1
            k += 1
        self.tree = [V for _ in range(2 * d - 1)]
        self.size = d 
    
    def update(self, i, a): 
        now = self.size - 1 + i
        if self.tree[now] != a:
            self.tree[now] = a
            while now > 0:
                now = (now - 1) // 2
                self.tree[now] = self.tree[2 * now + 1] | self.tree[2 * now + 2]

    def search(self, lower, higher, lbound, hbound, pos): 
        if higher <= lbound or hbound <= lower: return 0
        if lower <= lbound and hbound <= higher: return self.tree[pos]
        else:
            left = self.search(lower, higher, lbound, (lbound + hbound) // 2, 2 * pos + 1)
            right = self.search(lower, higher, (lbound + hbound) // 2, hbound, 2 * pos + 2)
            return left | right


def solve():
    input = sys.stdin.readline
    ab = ["a", "b", "c", "d", "e", "f", "g", "h", "i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"]
    abn = dict()
    for i, st in enumerate(ab): abn[st] = i
    N = int(input())
    S = list(input().strip("\n"))
    SegTree = RMQ(N, 0)
    for i, s in enumerate(S):
        ns = 1 << abn[s]
        SegTree.update(i, ns)
    Q = int(input())
    for _ in range(Q):
        t, l, r = input().strip("\n").split()
        if t == "1": SegTree.update(int(l) - 1, 1 << abn[r])
        elif t == "2": 
            bitans = SegTree.search(int(l) - 1, int(r), 0, SegTree.size, 0)
            ans = 0
            while bitans > 0:
                if bitans & 1 == 1: ans += 1
                bitans >>= 1
            print(ans)
    return 0

if __name__ =="__main__":
    solve()

Solution (Python):
import sys
input = sys.stdin.readline
N = int(input())
S = input().rstrip()
Q = int(input())
qs = [input().split() for i in range(Q)]

def ctoi(c):
    return ord(c) - ord('a')

bit = [[0]*(N+2) for _ in range(26)]
def bit_add(x,w,ci):
    while x <= N+1:
        bit[ci][x] += w
        x += (x & -x)
def bit_sum(x,ci):
    ret = 0
    while x > 0:
        ret += bit[ci][x]
        x -= (x & -x)
    return ret

for i,c in enumerate(S):
    bit_add(i+1,1,ctoi(c))

s = list(S)
ans = []
for a,b,c in qs:
    if a=='1':
        x = int(b)
        bit_add(x,1,ctoi(c))
        bit_add(x,-1, ctoi(s[x-1]))
        s[x-1] = c
    else:
        tmp = 0
        for i in range(26):
            if bit_sum(int(c),i) - bit_sum(int(b)-1,i) > 0:
                tmp += 1
        ans.append(tmp)
print(*ans, sep='\n')

Solution (Python):
class BIT:
    def __init__(self, n):
        self.n = n
        self.data = [0] * (n + 1)
        self.el = [0] * (n + 1)

    def sum(self, i):
        s = 0
        while i > 0:
            s += self.data[i]
            i -= i & -i
        return s

    def add(self, i, x):
        
        self.el[i] += x
        while i <= self.n:
            self.data[i] += x
            i += i & -i

    def get(self, i, j=None):
        if j is None:
            return self.el[i]
        return self.sum(j) - self.sum(i)


def main():
    import sys

    input = sys.stdin.readline

    n = int(input())  
    s = input().rstrip()

    base = ord('a')
    *s, = (ord(c) - base for c in s)

    q = int(input())  

    bits = [BIT(n + 1) for _ in range(26)]
    for i, x in enumerate(s, 1):
        bits[x].add(i, 1)

    ret = []
    for _ in range(q):
        query = iter(input().split())
        if next(query) == '1':
            
            pos = int(next(query))

            bf = s[pos - 1]
            char = ord(next(query)) - base

            bits[bf].add(pos, -1)
            s[pos - 1] = char

            bits[char].add(pos, 1)

        else:
            
            l = int(next(query))
            r = int(next(query))

            tt = 0
            for x in range(26):
                if bits[x].get(l - 1, r) > 0:
                    tt += 1
            ret.append(tt)

    print(*ret, sep='\n')


if __name__ == '__main__':
    main()

Solution (Python):
import sys

stdin = sys.stdin

ns = lambda: stdin.readline().rstrip()
ni = lambda: int(stdin.readline().rstrip())
nm = lambda: map(int, stdin.readline().split())
nl = lambda: list(map(int, stdin.readline().split()))

class SegTree:
    def __init__(self, N):
        self.N = N
        self._N = 1<<((N-1).bit_length())
        self.node = [0]*2*self._N

    def build(self,lis):
        for i in range(self.N):
            self.node[i+self._N-1] = lis[i]
        for i in range(self._N-2,-1,-1):
            self.node[i] = self.node[i*2+1] | self.node[i*2+2]
        return

    def update(self,i,x):
        i += self._N-1
        self.node[i] = x
        while i:
            i = (i-1)>>1
            self.node[i] = self.node[i*2+1] | self.node[i*2+2]

    def query(self,p,q,idx=0,a=0,b=None):
        if b is None:
            b = self._N
        if q <= p or b <= p or q <= a:
            return 0
        elif p <= a and b <= q:
            return self.node[idx]
        else:
            res1 = self.query(p,q,idx*2+1,a,(a+b)//2)
            res2 = self.query(p,q,idx*2+2,(a+b)//2,b)
            return res1 | res2

n = ni()
oa = ord('a')
conv = lambda x: 1<<(ord(x)-oa) 
s = list(map(conv, list(input())))
q = ni()
S = SegTree(n)
S.build(s)
for _ in range(q):
    x,y,z = input().split()
    if x == '1':
        y = int(y)
        S.update(y-1, conv(z))
    else:
        y = int(y)
        z = int(z)
        
        v = S.query(y-1,z)
        
        print(str(bin(v)).count('1'))

Solution (Python):
import sys, re
from collections import deque, defaultdict, Counter
from math import ceil, sqrt, hypot, factorial, pi, sin, cos, radians
from itertools import accumulate, permutations, combinations, product
from operator import itemgetter, mul
from copy import deepcopy
from string import ascii_lowercase, ascii_uppercase, digits
from bisect import bisect, bisect_left
from fractions import gcd
from heapq import heappush, heappop
from functools import reduce
def input(): return sys.stdin.readline().strip()
def INT(): return int(input())
def MAP(): return map(int, input().split())
def LIST(): return list(map(int, input().split()))
sys.setrecursionlimit(10 ** 9)
INF = float('inf')
mod = 10 ** 9 + 7

N = INT()
S = list(input())
Q = INT()

class Bit:
   def __init__(self, n):
       self.size = n
       self.tree = [0] * (n + 1)
   def sum(self, i):
       s = 0
       while i > 0:
           s += self.tree[i]
           i -= i & -i
       return s
   def add(self, i, x):
       while i <= self.size:
           self.tree[i] += x
           i += i & -i

dic_char = defaultdict(int)
for i, char in enumerate(ascii_lowercase):
	dic_char[char] = i

bits = [None]*len(ascii_uppercase)
for i in range(len(ascii_uppercase)):
	bits[i] = Bit(N)

for i in range(N):
	bits[dic_char[S[i]]].add(i+1, 1)

for _ in range(Q):
	a, b, c = input().split()
	if a == "1":  
		b = int(b)
		char = S[b-1]
		bits[dic_char[char]].add(b, -1)
		bits[dic_char[c]].add(b, 1)
		S[b-1] = c
	if a == "2":
		cnt = 0
		b, c = int(b), int(c)
		for i in range(len(ascii_uppercase)):
			cnt += bits[i].sum(c)-bits[i].sum(b-1) >= 1
		print(cnt)