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 in Rust (1.15.1) (judge verdict: Wrong Answer)

use std::io::*;
use std::str::FromStr;

pub fn read<T: FromStr>() -> T {
    let stdin = stdin();
    let stdin = stdin.lock();
    let token: String = stdin
        .bytes()
        .map(|c| c.expect("failed to read char") as char)
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect();
    token.parse().ok().expect("failed to parse token")
}

pub fn read_n<T: FromStr>(n: usize) -> Vec<T> {
    read_n_logic::<T>(n, vec![])
}

pub fn read_n_logic<T: FromStr>(n: usize, mut a: Vec<T>) -> Vec<T> {
    match n {
        0 => a,
        _ => {
            a.push(read::<T>());
            read_n_logic(n - 1, a)
        }
    }
}
use std::cmp::{max, min};

struct SegTree {
    v: Vec<i64>,
    next_two: usize,
}

impl SegTree {
    fn new(org: Vec<i64>) -> Self {
        let orglen = org.len();
        let mut next_two = 1;
        while next_two < orglen {
            next_two *= 2;
        }

        let vlen = next_two * 2;
        let mut v: Vec<i64> = vec![0; vlen];

        for i in (0..vlen).rev() {
            if next_two <= i && i - next_two < orglen {
                v[i] = org[i - next_two];
            }
            if i != 0 && i < next_two {
                v[i] = v[i * 2] | v[i * 2 + 1];
            }
        }
        SegTree {
            v: v,
            next_two: next_two,
        }
    }
    fn update(&mut self, idx: usize, nv: i64) {
        self.v[idx + self.next_two] = nv;
        let mut current_idx = idx + self.next_two;
        while current_idx != 1 {
            current_idx = current_idx / 2;
            self.v[current_idx] = self.v[current_idx * 2] | self.v[current_idx * 2 + 1];
        }
    }

    fn find(&self, a: usize, b: usize, l: usize, r: usize, k: usize) -> i64 {
        // println!("a:{}, b: {}, l: {}, r: {}, k: {}", a, b, l, r, k);
        if r < a || b < l {
            return 0;
        }

        if l == r {
            return self.v[l];
        }

        if a <= l && r <= b {
            return self.v[k];
        }

        let vl = self.find(a, b, l, (l + r - 1) / 2, k * 2);
        let vr = self.find(a, b, (l + r + 1) / 2, r, k * 2 + 1);
        return vl | vr;
    }
}

// ref: https://atcoder.jp/contests/abc157/submissions/10556514
fn main() {
    let n: usize = read();
    let s: String = read();
    let sc: Vec<char> = s.chars().collect();
    let sn: Vec<_> = sc
        .into_iter()
        .map(|c| 1 << (c as i32 - 'a' as i32))
        .collect();
    let mut st: SegTree = SegTree::new(sn);
    let q: usize = read();
    let mut next_two = 1;
    while next_two < n {
        next_two *= 2;
    }

    let mut anss = vec![];

    for _ in 0..q {
        let ty: usize = read();
        if ty == 1 {
            let i: usize = read();
            let s: String = read();
            let c: char = s.chars().collect::<Vec<char>>()[0];
            let cn: i64 = c as i64 - 'a' as i64;
            st.update(i, cn);
        } else {
            let i: usize = read();
            let r: usize = read();
            let mut pat = st.find(
                i + next_two - 1,
                r + next_two - 1,
                next_two,
                next_two * 2 - 1,
                1,
            );
            let mut pop = 0;
            while pat > 0 {
                if pat & 1 != 0 {
                    pop += 1;
                }
                pat >>= 1;
            }
            anss.push(pop);
        }
    }

    for i in anss {
        // let result: String = format!("{:0>keta$b}", i, keta = next_two as usize);
        // let cnt = result.chars().filter(|&x| x == '1').count();
        println!("{}", i);
    }
}