Meaning of the questions: give you a string, then this string some operations, 1 xa is to replace the characters on the x position into a, 2 xy is to ask the interval [x, y] how many different characters have on;
With 1 << (s [i] - 'a') on behalf of this character, the line segment to maintain the tree, is noted |
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <iostream>
using namespace std;
const int N = 1e5 + 10 ;
char s[ N] ;
int q, op, l, r;
char ch;
struct Node{
int l, r, sum;
} tree[ N<< 2 ] ;
void build ( int p, int l, int r) {
tree[ p] . l = l, tree[ p] . r = r;
if ( l== r) {
tree[ p] . sum = 1 << ( s[ l] - 'a' ) ;
return ;
}
int mid = l+ r>> 1 ;
build ( p<< 1 , l, mid) ;
build ( p<< 1 | 1 , mid+ 1 , r) ;
tree[ p] . sum = tree[ p<< 1 ] . sum| tree[ p<< 1 | 1 ] . sum;
}
void update ( int p, int pos, int x) {
int l = tree[ p] . l, r = tree[ p] . r;
if ( l== r) {
tree[ p] . sum = 1 << x;
return ;
}
int mid = l+ r>> 1 ;
if ( pos <= mid) {
update ( p<< 1 , pos, x) ;
} else update ( p<< 1 | 1 , pos, x) ;
tree[ p] . sum = tree[ p<< 1 ] . sum| tree[ p<< 1 | 1 ] . sum;
}
int query ( int p, int L, int R) {
int l = tree[ p] . l, r = tree[ p] . r;
if ( L<= l&& R>= r) return tree[ p] . sum;
int mid = l+ r>> 1 ;
int res = 0 ;
if ( L <= mid) res| = query ( p<< 1 , L, R) ;
if ( R > mid) res| = query ( p<< 1 | 1 , L, R) ;
return res;
}
int main ( ) {
scanf ( "%s" , s+ 1 ) ;
int n = strlen ( s+ 1 ) ;
build ( 1 , 1 , n) ;
scanf ( "%d" , & q) ;
while ( q-- ) {
scanf ( "%d" , & op) ;
if ( op== 1 ) {
scanf ( "%d %c" , & l, & ch) ;
update ( 1 , l, ch- 'a' ) ;
} else {
scanf ( "%d %d" , & l, & r) ;
int res = query ( 1 , l, r) ;
int ans = 0 ;
while ( res) {
if ( res& 1 ) ans++ ;
res>>= 1 ;
}
printf ( "%d\n" , ans) ;
}
}
return 0 ;
}