Buggy python submission (verdict: Time Limit Exceeded):
class BIT:

    def __init__(self, N):
        # NOTE: 1-indexed
        self.N = N
        self.data = [0] * (N + 1)

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

    def update(self, i, x):
        while i <= self.N:
            self.data[i] += x
            i += i & (- i)


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


def main():
    N = int(input())
    S = input()
    char_list = list(S)
    trees = [BIT(N) for _ in range(26)]
    for i, c in enumerate(S):
        trees[c2n(c)].update(i + 1, 1)
    Q = int(input())
    ans = list()
    for _ in range(Q):
        query = input().split()
        if query[0] == '1':
            _, i, c = query
            i = int(i) - 1
            before_c = char_list[i]
            char_list[i] = c
            trees[c2n(before_c)].update(i + 1, - 1)
            trees[c2n(c)].update(i + 1, 1)
        else:  # type '2'
            _, left, right = query
            left, right = int(left) - 1, int(right) - 1
            cnt = 0
            for i in range(26):
                n = trees[i].sum(right + 1) - trees[i].sum(left)
                if n > 0:
                    cnt += 1
            ans.append(cnt)
    for a in ans:
        print(a)


if __name__ == '__main__':
    main()

Fixed submission:
class BIT:

    def __init__(self, N):
        # NOTE: 1-indexed
        self.N = N
        self.data = [0] * (N + 1)

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

    def update(self, i, x):
        while i <= self.N:
            self.data[i] += x
            i += i & (- i)


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


def main():
    N = int(input())
    S = input()
    char_list = list(S)
    trees = [BIT(N) for _ in range(26)]
    for i, c in enumerate(S):
        trees[c2n(c)].update(i + 1, 1)
    Q = int(input())
    ans = list()
    for _ in range(Q):
        query = input().split()
        if query[0] == '1':
            _, i, c = query
            i = int(i) - 1
            before_c = char_list[i]
            char_list[i] = c
            trees[c2n(before_c)].update(i + 1, - 1)
            trees[c2n(c)].update(i + 1, 1)
        else:  # type '2'
            _, left, right = query
            left, right = int(left) - 1, int(right) - 1
            cnt = 0
            for i in range(26):
                n = trees[i].sum(right + 1) - trees[i].sum(left)
                if n > 0:
                    cnt += 1
            ans.append(cnt)
    for a in ans:
        print(a)


if __name__ == '__main__':
    main()

Buggy python submission (verdict: Time Limit Exceeded):
class SegTree:

    def __init__(self, N):
        self.N = N
        self.data = [0 for _ in range(2 * N)]

    def update(self, i, x):
        index = self.N + i - 1
        self.data[index] = x
        while index > 0:
            index = (index - 1) // 2  # parent
            self.data[index] = max(self.data[2 * index + 1], self.data[2 * index + 2])

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


def main():
    N = int(input())
    pw2 = 1
    while pw2 < N:
        pw2 *= 2
    S = input()
    Q = int(input())
    query_list = [input().split(' ') for _ in range(Q)]
    trees = [None for _ in range(26)]
    for cn in range(26):
        trees[cn] = SegTree(pw2)
    for i, c in enumerate(S):
        cn = ord(c) - ord('a')
        trees[cn].update(i, 1)
    for query in query_list:
        if query[0] == '1':
            # type 1 query
            i = int(query[1]) - 1
            new_cn = ord(query[2]) - ord('a')
            for cn in range(26):
                x = (1 if cn == new_cn else 0)
                trees[cn].update(i, x)
        else:
            # type 2 query
            left = int(query[1]) - 1
            right = int(query[2]) - 1
            kinds = sum([trees[cn].query(left, right + 1, 0, 0, pw2) for cn in range(26)])
            print(kinds)


if __name__ == '__main__':
    main()


Fixed submission:
class BIT:

    def __init__(self, N):
        # NOTE: 1-indexed
        self.N = N
        self.data = [0] * (N + 1)

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

    def update(self, i, x):
        while i <= self.N:
            self.data[i] += x
            i += i & (- i)


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


def main():
    N = int(input())
    S = input()
    char_list = list(S)
    trees = [BIT(N) for _ in range(26)]
    for i, c in enumerate(S):
        trees[c2n(c)].update(i + 1, 1)
    Q = int(input())
    ans = list()
    for _ in range(Q):
        query = input().split()
        if query[0] == '1':
            _, i, c = query
            i = int(i) - 1
            before_c = char_list[i]
            char_list[i] = c
            trees[c2n(before_c)].update(i + 1, - 1)
            trees[c2n(c)].update(i + 1, 1)
        else:  # type '2'
            _, left, right = query
            left, right = int(left) - 1, int(right) - 1
            cnt = 0
            for i in range(26):
                n = trees[i].sum(right + 1) - trees[i].sum(left)
                if n > 0:
                    cnt += 1
            ans.append(cnt)
    for a in ans:
        print(a)


if __name__ == '__main__':
    main()

Buggy python submission (verdict: Time Limit Exceeded):
class SegTree:

    def __init__(self, N):
        self.N = N
        self.data = [0 for _ in range(2 * N)]

    def update(self, i, x):
        index = self.N + i - 1
        self.data[index] = x
        while index > 0:
            index = (index - 1) // 2  # parent
            self.data[index] = max(self.data[2 * index + 1], self.data[2 * index + 2])

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


def main():
    chars = [chr(ord('a') + i) for i in range(26)]
    N = int(input())
    pw2 = 1
    while pw2 < N:
        pw2 *= 2
    S = input()
    Q = int(input())
    query_list = [input().split(' ') for _ in range(Q)]
    trees = dict()
    for c in chars:
        trees[c] = SegTree(pw2)
    for i, c in enumerate(S):
        trees[c].update(i, 1)
    for query in query_list:
        if query[0] == '1':
            # type 1 query
            i = int(query[1]) - 1
            new_c = query[2]
            for c in chars:
                x = (1 if c == new_c else 0)
                trees[c].update(i, x)
        else:
            # type 2 query
            left = int(query[1]) - 1
            right = int(query[2]) - 1
            kinds = sum([trees[c].query(left, right + 1, 0, 0, pw2) for c in chars])
            print(kinds)


if __name__ == '__main__':
    main()

Fixed submission:
class BIT:

    def __init__(self, N):
        # NOTE: 1-indexed
        self.N = N
        self.data = [0] * (N + 1)

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

    def update(self, i, x):
        while i <= self.N:
            self.data[i] += x
            i += i & (- i)


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


def main():
    N = int(input())
    S = input()
    char_list = list(S)
    trees = [BIT(N) for _ in range(26)]
    for i, c in enumerate(S):
        trees[c2n(c)].update(i + 1, 1)
    Q = int(input())
    ans = list()
    for _ in range(Q):
        query = input().split()
        if query[0] == '1':
            _, i, c = query
            i = int(i) - 1
            before_c = char_list[i]
            char_list[i] = c
            trees[c2n(before_c)].update(i + 1, - 1)
            trees[c2n(c)].update(i + 1, 1)
        else:  # type '2'
            _, left, right = query
            left, right = int(left) - 1, int(right) - 1
            cnt = 0
            for i in range(26):
                n = trees[i].sum(right + 1) - trees[i].sum(left)
                if n > 0:
                    cnt += 1
            ans.append(cnt)
    for a in ans:
        print(a)


if __name__ == '__main__':
    main()

Buggy python submission (verdict: Time Limit Exceeded):
class SegTree:

    def __init__(self, N):
        self.N = N
        self.data = [0 for _ in range(2 * N)]

    def update(self, i, x):
        index = self.N + i - 1
        self.data[index] = x
        while index > 0:
            index = (index - 1) // 2  # parent
            self.data[index] = max(self.data[2 * index + 1], self.data[2 * index + 2])

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

    def query(self, a, b):
        return self._query(a, b, 0, 0, self.N)


def main():
    chars = [chr(ord('a') + i) for i in range(26)]
    N = int(input())
    pw2 = 1
    while pw2 < N:
        pw2 *= 2
    S = input()
    Q = int(input())
    query_list = [input().split(' ') for _ in range(Q)]
    trees = dict()
    for c in chars:
        trees[c] = SegTree(pw2)
    for i, c in enumerate(S):
        trees[c].update(i, 1)
    for query in query_list:
        if query[0] == '1':
            # type 1 query
            i = int(query[1]) - 1
            new_c = query[2]
            for c in chars:
                x = (1 if c == new_c else 0)
                trees[c].update(i, x)
        else:
            # type 2 query
            left = int(query[1]) - 1
            right = int(query[2]) - 1
            kinds = sum([trees[c].query(left, right + 1) for c in chars])
            print(kinds)


if __name__ == '__main__':
    main()


Fixed submission:
class BIT:

    def __init__(self, N):
        # NOTE: 1-indexed
        self.N = N
        self.data = [0] * (N + 1)

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

    def update(self, i, x):
        while i <= self.N:
            self.data[i] += x
            i += i & (- i)


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


def main():
    N = int(input())
    S = input()
    char_list = list(S)
    trees = [BIT(N) for _ in range(26)]
    for i, c in enumerate(S):
        trees[c2n(c)].update(i + 1, 1)
    Q = int(input())
    ans = list()
    for _ in range(Q):
        query = input().split()
        if query[0] == '1':
            _, i, c = query
            i = int(i) - 1
            before_c = char_list[i]
            char_list[i] = c
            trees[c2n(before_c)].update(i + 1, - 1)
            trees[c2n(c)].update(i + 1, 1)
        else:  # type '2'
            _, left, right = query
            left, right = int(left) - 1, int(right) - 1
            cnt = 0
            for i in range(26):
                n = trees[i].sum(right + 1) - trees[i].sum(left)
                if n > 0:
                    cnt += 1
            ans.append(cnt)
    for a in ans:
        print(a)


if __name__ == '__main__':
    main()

Buggy python submission (verdict: Time Limit Exceeded):
class SegTree:

    def __init__(self, N):
        self.N = N
        self.data = [0 for _ in range(2 * N)]

    def update(self, i, x):
        index = self.N + i - 1
        self.data[index] = x
        while index > 0:
            index = (index - 1) // 2  # parent
            self.data[index] = max(self.data[2 * index + 1], self.data[2 * index + 2])

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

    def query(self, a, b):
        return self._query(a, b, 0, 0, self.N)


def main():
    chars = [chr(ord('a') + i) for i in range(26)]
    N = int(input())
    pw2 = 1
    while pw2 < N:
        pw2 *= 2
    S = input()
    Q = int(input())
    query_list = [input().split(' ') for _ in range(Q)]
    trees = dict()
    for c in chars:
        trees[c] = SegTree(pw2)
    for i, c in enumerate(S):
        trees[c].update(i, 1)
    for query in query_list:
        if query[0] == '1':
            # type 1 query
            i = int(query[1]) - 1
            new_c = query[2]
            for c in chars:
                x = (1 if c == new_c else 0)
                trees[c].update(i, x)
        else:
            # type 2 query
            left = int(query[1]) - 1
            right = int(query[2]) - 1
            kinds = sum([trees[c].query(left, right + 1) for c in chars])
            print(kinds)


if __name__ == '__main__':
    main()

Fixed submission:
class BIT:

    def __init__(self, N):
        # NOTE: 1-indexed
        self.N = N
        self.data = [0] * (N + 1)

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

    def update(self, i, x):
        while i <= self.N:
            self.data[i] += x
            i += i & (- i)


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


def main():
    N = int(input())
    S = input()
    char_list = list(S)
    trees = [BIT(N) for _ in range(26)]
    for i, c in enumerate(S):
        trees[c2n(c)].update(i + 1, 1)
    Q = int(input())
    ans = list()
    for _ in range(Q):
        query = input().split()
        if query[0] == '1':
            _, i, c = query
            i = int(i) - 1
            before_c = char_list[i]
            char_list[i] = c
            trees[c2n(before_c)].update(i + 1, - 1)
            trees[c2n(c)].update(i + 1, 1)
        else:  # type '2'
            _, left, right = query
            left, right = int(left) - 1, int(right) - 1
            cnt = 0
            for i in range(26):
                n = trees[i].sum(right + 1) - trees[i].sum(left)
                if n > 0:
                    cnt += 1
            ans.append(cnt)
    for a in ans:
        print(a)


if __name__ == '__main__':
    main()