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: Accepted)

#![allow(non_snake_case,unused_imports,dead_code)]
use std::io::Read;
use std::cmp::max;
use std::cmp::min;
use std::str::FromStr;
use std::collections::HashMap;
use std::collections::HashSet;
use std::collections::BinaryHeap;
use std::cmp::Ordering;

fn comp_f64(a: &f64, b: &f64) -> Ordering {
    if a < b {
        return Ordering::Less;
    } else if a > b {
        return Ordering::Greater;
    }
    Ordering::Equal
}

fn main() {

    let mut buf = String::new();
    std::io::stdin().read_to_string(&mut buf).unwrap();
    let mut buf_it = buf.split_whitespace();

    let N = buf_it.next().unwrap().parse::<usize>().unwrap();
    let S = buf_it.next().unwrap().chars().collect::<Vec<_>>();
    let Q = buf_it.next().unwrap().parse::<usize>().unwrap();

    let Query = (0..Q).map(|_|
        (buf_it.next().unwrap().parse::<usize>().unwrap(),
        buf_it.next().unwrap(),
        buf_it.next().unwrap())
    ).collect::<Vec<_>>();

    let mut Ta = SegmentTree::new(N,max,0);
    let mut Tb = SegmentTree::new(N,max,0);
    let mut Tc = SegmentTree::new(N,max,0);
    let mut Td = SegmentTree::new(N,max,0);
    let mut Te = SegmentTree::new(N,max,0);
    let mut Tf = SegmentTree::new(N,max,0);
    let mut Tg = SegmentTree::new(N,max,0);
    let mut Th = SegmentTree::new(N,max,0);
    let mut Ti = SegmentTree::new(N,max,0);
    let mut Tj = SegmentTree::new(N,max,0);
    let mut Tk = SegmentTree::new(N,max,0);
    let mut Tl = SegmentTree::new(N,max,0);
    let mut Tm = SegmentTree::new(N,max,0);
    let mut Tn = SegmentTree::new(N,max,0);
    let mut To = SegmentTree::new(N,max,0);
    let mut Tp = SegmentTree::new(N,max,0);
    let mut Tq = SegmentTree::new(N,max,0);
    let mut Tr = SegmentTree::new(N,max,0);
    let mut Ts = SegmentTree::new(N,max,0);
    let mut Tt = SegmentTree::new(N,max,0);
    let mut Tu = SegmentTree::new(N,max,0);
    let mut Tv = SegmentTree::new(N,max,0);
    let mut Tw = SegmentTree::new(N,max,0);
    let mut Tx = SegmentTree::new(N,max,0);
    let mut Ty = SegmentTree::new(N,max,0);
    let mut Tz = SegmentTree::new(N,max,0);
    
    for (i,&c) in S.iter().enumerate(){
        match c {
            'a' => Ta.set(i,1),
            'b' => Tb.set(i,1),
            'c' => Tc.set(i,1),
            'd' => Td.set(i,1),
            'e' => Te.set(i,1),
            'f' => Tf.set(i,1),
            'g' => Tg.set(i,1),
            'h' => Th.set(i,1),
            'i' => Ti.set(i,1),
            'j' => Tj.set(i,1),
            'k' => Tk.set(i,1),
            'l' => Tl.set(i,1),
            'm' => Tm.set(i,1),
            'n' => Tn.set(i,1),
            'o' => To.set(i,1),
            'p' => Tp.set(i,1),
            'q' => Tq.set(i,1),
            'r' => Tr.set(i,1),
            's' => Ts.set(i,1),
            't' => Tt.set(i,1),
            'u' => Tu.set(i,1),
            'v' => Tv.set(i,1),
            'w' => Tw.set(i,1),
            'x' => Tx.set(i,1),
            'y' => Ty.set(i,1),
            'z' => Tz.set(i,1),
            _ => (),
        }
    }

    for j in 0..Q{
        if Query[j].0 == 1{
            let i = Query[j].1.parse::<usize>().unwrap() -1;
            let c = Query[j].2.chars().collect::<Vec<_>>()[0];
            Ta.set(i,0);
            Tb.set(i,0);
            Tc.set(i,0);
            Td.set(i,0);
            Te.set(i,0);
            Tf.set(i,0);
            Tg.set(i,0);
            Th.set(i,0);
            Ti.set(i,0);
            Tj.set(i,0);
            Tk.set(i,0);
            Tl.set(i,0);
            Tm.set(i,0);
            Tn.set(i,0);
            To.set(i,0);
            Tp.set(i,0);
            Tq.set(i,0);
            Tr.set(i,0);
            Ts.set(i,0);
            Tt.set(i,0);
            Tu.set(i,0);
            Tv.set(i,0);
            Tw.set(i,0);
            Tx.set(i,0);
            Ty.set(i,0);
            Tz.set(i,0);

            match c {
                'a' => Ta.set(i,1),
                'b' => Tb.set(i,1),
                'c' => Tc.set(i,1),
                'd' => Td.set(i,1),
                'e' => Te.set(i,1),
                'f' => Tf.set(i,1),
                'g' => Tg.set(i,1),
                'h' => Th.set(i,1),
                'i' => Ti.set(i,1),
                'j' => Tj.set(i,1),
                'k' => Tk.set(i,1),
                'l' => Tl.set(i,1),
                'm' => Tm.set(i,1),
                'n' => Tn.set(i,1),
                'o' => To.set(i,1),
                'p' => Tp.set(i,1),
                'q' => Tq.set(i,1),
                'r' => Tr.set(i,1),
                's' => Ts.set(i,1),
                't' => Tt.set(i,1),
                'u' => Tu.set(i,1),
                'v' => Tv.set(i,1),
                'w' => Tw.set(i,1),
                'x' => Tx.set(i,1),
                'y' => Ty.set(i,1),
                'z' => Tz.set(i,1),
                _ => (),
            }
        } else {
            let l = Query[j].1.parse::<usize>().unwrap() -1;
            let r = Query[j].2.parse::<usize>().unwrap();
            let mut ans = 0;
            ans += Ta.get(l,r);
            ans += Tb.get(l,r);
            ans += Tc.get(l,r);
            ans += Td.get(l,r);
            ans += Te.get(l,r);
            ans += Tf.get(l,r);
            ans += Tg.get(l,r);
            ans += Th.get(l,r);
            ans += Ti.get(l,r);
            ans += Tj.get(l,r);
            ans += Tk.get(l,r);
            ans += Tl.get(l,r);
            ans += Tm.get(l,r);
            ans += Tn.get(l,r);
            ans += To.get(l,r);
            ans += Tp.get(l,r);
            ans += Tq.get(l,r);
            ans += Tr.get(l,r);
            ans += Ts.get(l,r);
            ans += Tt.get(l,r);
            ans += Tu.get(l,r);
            ans += Tv.get(l,r);
            ans += Tw.get(l,r);
            ans += Tx.get(l,r);
            ans += Ty.get(l,r);
            ans += Tz.get(l,r);
            println!("{}",ans);
        }
    }
}

struct SegmentTree<N,F>
where F:Fn(N,N) ->N{
    n: usize,
    T: Vec<N>,
    func: F,
    identity: N,
}

impl<N:Copy,F> SegmentTree<N,F>
where F:Fn(N,N) ->N {
    fn new(n:usize,func:F,identity:N) -> SegmentTree<N,F>{
        let mut T = SegmentTree { n:n,T:Vec::new(),func:func,identity:identity};
        T.init();
        T
    }
    fn init(&mut self){
        self.n = 1<<format!("{:b}",self.n-1).len();
        self.T = (0..(2*self.n-1)).map(|_| self.identity).collect();
    }
    fn set(&mut self,index:usize,value:N){
        let i = index + self.n - 1;
        self.T[i] = value;
        self._update_parent((i-1)/2);
    }
    fn _update_parent(&mut self,i:usize){
        self.T[i] = (self.func)(self.T[i*2+1],self.T[i*2+2]);
        if i>0 { self._update_parent((i-1)/2)}
    }
    fn get(&self,l:usize,r:usize) -> N{
    self._get(l,r,0,0,self.n)
    }
    fn _get(&self,l:usize,r:usize,i:usize,a:usize,b:usize) -> N{
        if l<=a && b<=r {
            self.T[i]
        } else if b<=l || r<=a {
            self.identity
        } else{
            (self.func)(self._get(l,r,2*i+1,a,(a+b)/2),
                        self._get(l,r,2*i+2,(a+b)/2,b))
        }
    }
}