题意
给一个10^5之内的字符串(小写字母)时限2s
输入n,有n个操作 (n<10^5)
当操作是1的时候,输入位置x和改变的字母
当操作是2的时候,输入区间l和r,有多少不同的字母
思路
二维树状数组
#include<iostream> #include<cstdio> #include<cstring> #include<queue> #include<map> #define lowbit(x) x&(-x) using namespace std; const int maxn=1e5+10; char s[maxn]; int l,n,yi,er,san; char c; struct node{ int tr[maxn]; void inint(){ memset(tr,0,sizeof(tr)); } void updata(int x,int y){ for(int i=x; i<=l; i+=lowbit(i)){ tr[i]+=y; } } int geshu(int x,int y){ int sum1=0,sum2=0; for(int i=x; i>0; i-=lowbit(i)){ sum1+=tr[i]; } for(int i=y; i>0; i-=lowbit(i)){ sum2+=tr[i]; } return sum2-sum1; } } a[27]; int main(){ while(~scanf("%s",&s)){ for(int i=0; i<26; i++){ a[i].inint(); } l=strlen(s); for(int i=0; i<l; i++){ a[s[i]-'a'].updata(i+1,1); } scanf("%d",&n); for(int i=0; i<n; i++){ scanf("%d",&yi); if(yi==1){ scanf("%d %c",&er,&c); er--; a[s[er]-'a'].updata(er+1,-1); s[er]=c; a[s[er]-'a'].updata(er+1,1); } else{ scanf("%d%d",&er,&san); int ans=0; er--; for(int i=0; i<26; i++){ //cout<<i<<" "<<a[i].geshu(er,san)<<endl; if(a[i].geshu(er,san)){ ans+=1; } } printf("%d ",ans); } } } return 0; }