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;
//     }
// }
struct Segtree<T, F> {
    n: usize,
    dat: Vec<T>,
    op: F,
    unit: T,
}
impl<T: Clone, F: Fn(&T, &T) -> T> Segtree<T, F> {
    #[allow(dead_code)]
    fn new(n: usize, op: F, unit: T) -> Self {
        Segtree {
            n: n,
            dat: vec![unit.clone(); 2 * n.next_power_of_two() - 1],
            op: op,
            unit: unit,
        }
    }
    #[allow(dead_code)]
    fn from_vec(v: Vec<T>, op: F, unit: T) -> Self {
        use std::iter::repeat;
        let n = v.len();
        let base = n.next_power_of_two();
        let mut dat: Vec<_> = repeat(unit.clone())
            .take(base - 1)
            .chain(v.into_iter())
            .chain(repeat(unit.clone()).take(base - n))
            .collect();
        assert_eq!(dat.len(), 2 * base - 1);
        for i in (0..base - 1).rev() {
            dat[i] = op(&dat[i * 2 + 1], &dat[i * 2 + 2]);
        }
        Segtree {
            n: base,
            dat: dat,
            op: op,
            unit: unit,
        }
    }
    fn update(&mut self, mut k: usize, x: T) {
        k += self.n - 1;
        self.dat[k] = x;
        while k > 0 {
            k = (k - 1) / 2;
            self.dat[k] = (self.op)(&self.dat[k * 2 + 1], &self.dat[k * 2 + 2]);
        }
    }
    fn accum(&self, a: usize, b: usize) -> T {
        self.accum_inner(a, b, 0, 0, self.n)
    }
    fn accum_inner(&self, a: usize, b: usize, k: usize, l: usize, r: usize) -> T {
        if r <= a || b <= l {
            return self.unit.clone();
        }
        if a <= l && r <= b {
            return self.dat[k].clone();
        }
        let vl = self.accum_inner(a, b, k * 2 + 1, l, (l + r) / 2);
        let vr = self.accum_inner(a, b, k * 2 + 2, (l + r) / 2, r);
        (self.op)(&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::from_vec(sn, |x, y| x | y, 0);
    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 = 1 << c as i64 - 'a' as i64;
            st.update(i, cn);
        } else {
            let mut l: usize = read();
            let r: usize = read();
            l -= 1;
            // let ans = st.find(
            //     i + next_two - 1,
            //     r + next_two - 1,
            //     next_two,
            //     next_two * 2 - 1,
            //     1,
            // );
            let mut pat = st.accum(l, r);
            let mut pop = 0;
            while pat > 0 {
                if pat & 1 != 0 {
                    pop += 1;
                }
                pat >>= 1;
            }
            anss.push(pop);
        }
    }

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