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.



Sample input:
7
abcdbbd
6
2 3 6
1 5 z
2 1 1
1 4 a
1 7 d
2 1 7


Sample output:
3
1
5

Submission status: Time Limit Exceeded

Solution code:

import operator
class SegmentTree:
    def __init__(self, size, fn=operator.add, default=None, initial_values=None):
        """
        :param int size:
        :param callable fn: 区間に適用する関数。引数を 2 つ取る。min, max, operator.xor など
        :param default:
        :param list initial_values:
        """
        default = default or 0

        # size 以上である最小の 2 冪を size とする
        n = 1
        while n < size:
            n *= 2
        self._size = n
        self._fn = fn

        self._tree = [default] * (self._size * 2 - 1)
        if initial_values:
            i = self._size - 1
            for v in initial_values:
                self._tree[i] = v
                i += 1
            i = self._size - 2
            while i >= 0:
                self._tree[i] = self._fn(self._tree[i * 2 + 1], self._tree[i * 2 + 2])
                i -= 1

    def set(self, i, value):
        """
        i 番目に value を設定
        :param int i:
        :param value:
        :return:
        """
        x = self._size - 1 + i
        self._tree[x] = value

        while x > 0:
            x = (x - 1) // 2
            self._tree[x] = self._fn(self._tree[x * 2 + 1], self._tree[x * 2 + 2])

    def add(self, i, value):
        """
        もとの i 番目と value に fn を適用したものを i 番目に設定
        :param int i:
        :param value:
        :return:
        """
        x = self._size - 1 + i
        self.set(i, self._fn(self._tree[x], value))

    def get(self, from_i, to_i=None, k=0, L=None, r=None):
        """
        [from_i, to_i) に fn を適用した結果を返す
        :param int from_i:
        :param int to_i:
        :param int k: self._tree[k] が、[L, r) に fn を適用した結果を持つ
        :param int L:
        :param int r:
        :return:
        """
        if to_i is None:
            return self._tree[self._size - 1 + from_i]

        L = 0 if L is None else L
        r = self._size if r is None else r

        if from_i <= L and r <= to_i:
            return self._tree[k]

        if to_i <= L or r <= from_i:
            return None

        ret_L = self.get(from_i, to_i, k * 2 + 1, L, (L + r) // 2)
        ret_r = self.get(from_i, to_i, k * 2 + 2, (L + r) // 2, r)
        if ret_L is None:
            return ret_r
        if ret_r is None:
            return ret_L
        return self._fn(ret_L, ret_r)

    def __len__(self):
        return self._size

def resolve():
    N = int(input())
    S = input()
    Q = int(input())

    seg = SegmentTree(N, fn=operator.or_)
    for i in range(N):
        s = 2 ** (ord(S[i]) - ord('a'))
        seg.set(i, s)

    for _ in range(Q):
        act, q1, q2 = input().split()
        if act == "1":
            # 文字変更
            idx = int(q1) - 1
            s_bin = 1 << (ord(q2) - ord('a'))
            seg.set(idx, s_bin)
        else:
            # L,R区間の文字種を出力
            l = int(q1)-1
            r = int(q2)
            x = bin(seg.get(l, r))
            print(x.count("1"))


if __name__ == "__main__":
    resolve()

Submission status: Time Limit Exceeded

Solution code:
n = int(input())
s = list(input())
q = int(input())
for i in range(q):
  a,b,c = input().split()
  if a=='1':
    s[int(b)-1] = c
  else:
    t = s[int(b)-1:int(c)]
    print(len(set(t)))

Submission status: Time Limit Exceeded

Solution code:
alp="abcdefghijklmnopqrstuvwxyz"

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

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

#####ide_ele#####
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)

Submission status: Time Limit Exceeded

Solution code:
alp="abcdefghijklmnopqrstuvwxyz"

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

for i in range(q):
    que=input().split()
    if que[0]=="1":
        s[int(que[1])-1]=que[2]
    else:
        print(len(set(s[int(que[1])-1:int(que[2])])))

Submission status: Time Limit Exceeded

Solution code:
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):
            # print([BIT[i].get(r),BIT[i].get(l)])
            res += (BIT[i].get(r) > BIT[i].get(l-1))
        ans.append(str(res))
print("\n".join(ans))

Submission status: Time Limit Exceeded

Solution code:
import sys
# import re
import math
import collections
# import decimal
import bisect
import itertools
import fractions
# import functools
import copy
# import heapq
import decimal
# import statistics
import queue

# import numpy as np

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

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


# ===CODE===
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
            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()

Submission status: Time Limit Exceeded

Solution code:
import sys
# import re
import math
import collections
# import decimal
import bisect
import itertools
import fractions
# import functools
import copy
# import heapq
import decimal
# import statistics
import queue

# import numpy as np

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

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


# ===CODE===
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
            for i in range(26):
                del_idx = bisect.bisect_left(alphabet_idx[i], a)
                if del_idx < len(alphabet_idx[i]):
                    if alphabet_idx[i][del_idx] == a:
                        del alphabet_idx[i][del_idx]
                        break

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

        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()

Submission status: Time Limit Exceeded

Solution code:
# Treapの実装
from random import random
class Treap():
    def __init__(self):
        # left, right, parent, root, debrisはdataのindexを格納
        self.data = []
        self.p = []
        self.left = []
        self.right = []
        self.parent = []
        self.root = None

    # xが見つかればxのindex、見つからなければ探索した最後のnodeのindexを返す
    def find(self, x):
        i = self.root
        while True:
            if self.data[i] == x:
                return i
            elif self.data[i] < x:
                if self.right[i] == None:
                    return i
                else:
                    i = self.right[i]
            elif self.left[i] == None:
                return i
            else:
                i = self.left[i]
    
    # 追加する場所のindexを返す
    def next_place(self):
        self.data.append(None)
        self.p.append(random())
        self.left.append(None)
        self.right.append(None)
        self.parent.append(None)
        return len(self.data) - 1

    def add(self, x):
        if self.root == None:
            self.data = [x]
            self.p = [random()]
            self.left = [None]
            self.right = [None]
            self.parent = [None]
            self.root = 0
        else:
            p = self.find(x) # p = (xの親となるindex)
            if self.data[p] != x:
                i = self.next_place()
                self.data[i] = x
                self.parent[i] = p
                if self.data[p] < x:
                    self.right[p] = i
                else:
                    self.left[p] = i
            
            # heap性の確保
            while self.parent[i] != None and self.p[i] < self.p[self.parent[i]]:
                if self.left[self.parent[i]] == i:
                    self.rotateRight(self.parent[i])
                else:
                    self.rotateLeft(self.parent[i])
    
    def remove(self, x):
        if self.root == None:
            return None
        i = self.find(x)
        if self.data[i] == x:
            while self.left[i] != None and self.right[i] != None:
                if self.p[self.left[i]] > self.p[self.right[i]]:
                    self.rotateLeft(i)
                else:
                    self.rotateRight(i)

            # parent[j]をparent[i]に変更
            if self.left[i] == None and self.right[i] == None:
                j = None
            elif self.left[i] == None:
                j = self.right[i]
                self.parent[j] = self.parent[i]
            else:
                j = self.left[i]
                self.parent[j] = self.parent[i]

            # parent[i]の子をjに変更
            if self.root == i:
                self.root = j
            elif self.left[self.parent[i]] == i:
                self.left[self.parent[i]] = j
            else:
                self.right[self.parent[i]] = j

    def rotateRight(self, u):
        w = self.left[u]
        if self.root == u:
            self.root = w
        elif self.left[self.parent[u]] == u:
            self.left[self.parent[u]] = w
        else:
            self.right[self.parent[u]] = w
        self.parent[w] = self.parent[u]
        self.left[u] = self.right[w]
        if self.right[w] != None:
            self.parent[self.right[w]] = u
        self.parent[u] = w
        self.right[w] = u
    
    def rotateLeft(self, u):
        w = self.right[u]
        if self.root == u:
            self.root = w
        elif self.left[self.parent[u]] == u:
            self.left[self.parent[u]] = w
        else:
            self.right[self.parent[u]] = w
        self.parent[w] = self.parent[u]
        self.right[u] = self.left[w]
        if self.left[w] != None:
            self.parent[self.left[w]] = u
        self.parent[u] = w
        self.left[w] = u

    def search(self, l, r):
        i = self.root
        while i != None:
            if l <= self.data[i] <= r:
                return True
            elif self.data[i] < l:
                i = self.right[i]
            else:
                i = self.left[i]
        return False


from sys import stdin
def input():
    return stdin.readline().strip()

def order(a):
    return ord(a) - 97


def main():

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

    # alphabet毎に整理
    alp = [Treap() for _ in range(26)]
    from random import shuffle
    l = [i for i in range(n)]
    shuffle(l)
    for i in l:
        alp[order(s[i])].add(i)

    # クエリ処理
    ans = []
    for _ in range(q):
        a, b, c = input().split()
        b = int(b) - 1

        # type1
        if a == '1':
            alp[order(s[b])].remove(b)
            alp[order(c)].add(b)
            s[b] = c

        # type2
        else:
            c = int(c) - 1
            num = 0
            for i in alp:
                if i.search(b, c):
                    num += 1
            ans.append(num)

    for i in ans:
        print(i)

main()

Submission status: Time Limit Exceeded

Solution code:
# セグメント木 最新バージョン
#verify
class SegTree():
    # 1-indexed
    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):
        # [L,R)でX以下の物で最大indexを取得
        return self.fMi(L, R, X, 1, 0, 2**self.K)

    def find_min_index(self, L, R, X):
        # [L,R) でX以下の物で最小のindexを取得する
        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)

Submission status: Time Limit Exceeded

Solution code:
import bisect

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()

Submission status: Time Limit Exceeded

Solution code:
import bisect

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.keys():
            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.keys():
                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()

Submission status: Time Limit Exceeded

Solution code:
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.keys():
            set_dic[s] = {i+1}
        else:
            set_dic[s].add(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].discard(i)
            if c not in set_dic.keys():
                set_dic[c] = {i}
            else:
                set_dic[c].add(i)
            S[i-1] = c
        else:
            l = int(query2)
            r = int(query3)
            ansset = set()
            ans = 0
            for eachset in set_dic.values():
                for i in range(l, r + 1):
                    if i in eachset:
                        ans += 1
                        break
            anslist.append(ans)

    for i in anslist:
        print(i)

if __name__ == '__main__':
    solve()

Submission status: Time Limit Exceeded

Solution code:
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.keys():
            set_dic[s] = {i+1}
        else:
            set_dic[s].add(i+1)

    anslist = []

    for _ in range(Q):
        query1, query2, query3 = input().split()
        if query1 == "1":
            i = int(query2)
            c = query3
            for l in set_dic.values():
                l.discard(i)
            if c not in set_dic.keys():
                set_dic[c] = {i}
            else:
                set_dic[c].add(i)
        else:
            l = int(query2)
            r = int(query3)
            ansset = set()
            ans = 0
            for eachset in set_dic.values():
                for i in range(l, r + 1):
                    if i in eachset:
                        ans += 1
                        break
            anslist.append(ans)

    for i in anslist:
        print(i)

if __name__ == '__main__':
    solve()

Submission status: Time Limit Exceeded

Solution code:
N = int(input())
S = list(input())
Q = int(input())
set_dic = {}

for i, s in enumerate(S):
    if s not in set_dic.keys():
        set_dic[s] = {i+1}
    else:
        set_dic[s].add(i+1)

anslist = []

for _ in range(Q):
    query1, query2, query3 = input().split()
    if query1 == "1":
        i = int(query2)
        c = query3
        for l in set_dic.values():
            l.discard(i)
        if c not in set_dic.keys():
            set_dic[c] = {i}
        else:
            set_dic[c].add(i)
    else:
        l = int(query2)
        r = int(query3)
        ansset = set()
        ans = 0
        for eachset in set_dic.values():
            for i in range(l, r + 1):
                if i in eachset:
                    ans += 1
                    break
        anslist.append(ans)

for i in anslist:
    print(i)

Submission status: Time Limit Exceeded

Solution code:
N = int(input())
S = list(input())
Q = int(input())
set_dic = {}

for i, s in enumerate(S):
    if s not in set_dic.keys():
        set_dic[s] = {i+1}
    else:
        set_dic[s].add(i+1)

anslist = []
count = 0

for _ in range(Q):
    query1,query2,query3 = input().split()
    if query1 == "1":
        i = int(query2)
        c = query3
        for l in set_dic.values():
            l.discard(i)
        if c not in set_dic.keys():
            set_dic[c] = {i}
        else:
            set_dic[c].add(i)
    else:
        l = int(query2)
        r = int(query3)
        ansset = set()
        for i in range(l, r + 1):
            for key, eachset in set_dic.items():
                if i in eachset:
                    ansset.add(key)
                    break
        ans = len(ansset)
        anslist.append(ans)
        count += 1

for i in anslist:
    print(i)

Submission status: Time Limit Exceeded

Solution code:
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()

Submission status: Time Limit Exceeded

Solution code:
#セグメント木のverify

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):
        # 0-indexでa[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):
        # 0-indexで[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)

Submission status: Time Limit Exceeded

Solution code:
N = int(input())
S = input()
Q = int(input())

S = [i for i in S]

for _ in range(Q):
  a,b,c = input().split()
  if a == '1':
    S[int(b)-1] = c
  else:
    b = int(b)-1
    c = int(c)
    print(len(set(S[b:c])))