Codeforces #590 D 二维树状数组

时间:2022-09-01 05:04:19

题意

给一个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+;
char s[maxn];
int l,n,yi,er,san;
char c;
struct node{
int tr[maxn];
void inint(){
memset(tr,,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=,sum2=;
for(int i=x; i>; i-=lowbit(i)){
sum1+=tr[i];
}
for(int i=y; i>; i-=lowbit(i)){
sum2+=tr[i];
}
return sum2-sum1;
}
} a[];
int main(){ while(~scanf("%s",&s)){
for(int i=; i<; i++){
a[i].inint();
}
l=strlen(s);
for(int i=; i<l; i++){
a[s[i]-'a'].updata(i+,);
}
scanf("%d",&n);
for(int i=; i<n; i++){
scanf("%d",&yi);
if(yi==){
scanf("%d %c",&er,&c);
er--;
a[s[er]-'a'].updata(er+,-);
s[er]=c;
a[s[er]-'a'].updata(er+,); }
else{
scanf("%d%d",&er,&san);
int ans=;
er--;
for(int i=; i<; i++){
//cout<<i<<" "<<a[i].geshu(er,san)<<endl;
if(a[i].geshu(er,san)){
ans+=;
}
}
printf("%d\n",ans);
}
}
}
return ;
}