题意
给一个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