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 C (GCC 5.4.1) (judge verdict: Accepted)

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h> // uint64_t

#define max(a,b) ((a) > (b) ? (a) : (b))
#define min(a,b) ((a) > (b) ? (b) : (a))

#define STR_MAX 500000
// 524288
#define NUM_MAX (1<<19)
#define BUF_SIZE (STR_MAX+100)
#define QUERY_MAX 20000
#define LOWER_NUM 26

int get_int(void) {
  int num;
  scanf("%d", &num);
  return num;
}

int get_intch(int *a, char *ch) {
    return scanf("%d %c", a, ch);
}

int get_int2(int *a, int *b) {
    return scanf("%d %d", a, b);
}

// include '\n'
int get_str(char *str, int size)
{
    char format[100];
    if (size == 0)
        return 0;
    snprintf(format, sizeof(format), "%%%ds", size);
    scanf(format, str);
    return 0;
}

enum type {
    COMMAND_UPDATE = 1,
    COMMAND_GET
};

// assume that 'a' - 'z'
char get_pos(char ch) {
    return ch - 'a';
}

void update(char *seg, int num, int idx, int flag) {
    int node = num + idx;
    seg[node] = flag;
    node /= 2;
    while(node) {
        int left = node*2;
        int right = node*2+1;
        // remove old
        seg[node] = seg[left] | seg[right];
        node/=2;
    }
    return;
}

struct range {
    int start;
    int end;
};

int is_overlap(struct range r1, struct range r2) {
    return r1.end >= r2.start && r2.end >= r1.start;
}

int is_contain(struct range this, struct range in) {
    return in.start <= this.start && in.end >= this.end;
}

char get(char *seg, struct range r, int node, struct range nr) {
    if(!is_overlap(r, nr)) return 0;
    if(is_contain(nr, r)) {
        return seg[node];
    }
    // otherwise
    struct range left = {nr.start, (nr.start+nr.end)/2};
    struct range right = {left.end+1, nr.end};
    return get(seg, r, node*2, left) | get(seg, r, node*2+1, right);
}

int main(void) {
    int _num = get_int();
    int num = 1;
    while(_num >= num) num *= 2;
    static char str[BUF_SIZE];
    get_str(str, _num);

    int queries = get_int();
    static char seg[LOWER_NUM][NUM_MAX*2];
    static int ans[QUERY_MAX];
    int aidx = 0;
    int i, j;
    // initialization
    for(i = 0; i < _num; i++) {
        int idx = get_pos(str[i]);
        update(seg[idx], num, i, 1);
    }

    struct range whole = {0, num-1};
    for(i = 0; i < queries; i++) {
        int type = get_int();
        switch(type) {
            case COMMAND_UPDATE:
                {
                    int idx; char newch;
                    get_intch(&idx, &newch);
                    idx--;
                    int old_pos = get_pos(str[idx]);
                    int pos = get_pos(newch);
                    update(seg[old_pos], num, idx, 0);
                    update(seg[pos], num, idx, 1);
                    str[idx] = newch;
                }
                break;
            case COMMAND_GET:
                {
                    int start, end;
                    get_int2(&start, &end);
                    start--; end--;
                    struct range r = {start, end};
                    int res = 0;
                    for(j = 0; j < LOWER_NUM; j++) {
                        res += get(seg[j], r, 1, whole);
                    }
                    ans[aidx++] = res;
                }
                break;
            default:
                break;
        }
    }
    for(i = 0; i < aidx; i++) {
        printf("%d\n", ans[i]);
    }
}