题意
给一个10^5之内的字符串(小写字母)时限2s
输入n,有n个操作 (n<10^5)
当操作是1的时候,输入位置x和改变的字母
当操作是2的时候,输入区间l和r,有多少不同的字母
思路
二维树状数组

1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 #include<queue>
5 #include<map>
6 #define lowbit(x) x&(-x)
7 using namespace std;
8 const int maxn=1e5+10;
9 char s[maxn];
10 int l,n,yi,er,san;
11 char c;
12 struct node{
13 int tr[maxn];
14 void inint(){
15 memset(tr,0,sizeof(tr));
16 }
17 void updata(int x,int y){
18 for(int i=x; i<=l; i+=lowbit(i)){
19 tr[i]+=y;
20 }
21 }
22 int geshu(int x,int y){
23 int sum1=0,sum2=0;
24 for(int i=x; i>0; i-=lowbit(i)){
25 sum1+=tr[i];
26 }
27 for(int i=y; i>0; i-=lowbit(i)){
28 sum2+=tr[i];
29 }
30 return sum2-sum1;
31 }
32 } a[27];
33 int main(){
34
35 while(~scanf("%s",&s)){
36 for(int i=0; i<26; i++){
37 a[i].inint();
38 }
39 l=strlen(s);
40 for(int i=0; i<l; i++){
41 a[s[i]-'a'].updata(i+1,1);
42 }
43 scanf("%d",&n);
44 for(int i=0; i<n; i++){
45 scanf("%d",&yi);
46 if(yi==1){
47 scanf("%d %c",&er,&c);
48 er--;
49 a[s[er]-'a'].updata(er+1,-1);
50 s[er]=c;
51 a[s[er]-'a'].updata(er+1,1);
52
53 }
54 else{
55 scanf("%d%d",&er,&san);
56 int ans=0;
57 er--;
58 for(int i=0; i<26; i++){
59 //cout<<i<<" "<<a[i].geshu(er,san)<<endl;
60 if(a[i].geshu(er,san)){
61 ans+=1;
62 }
63 }
64 printf("%d\n",ans);
65 }
66 }
67 }
68 return 0;
69 }
来源:https://www.cnblogs.com/luoyugongxi/p/12190090.html
