Codeforces Round #590 (Div. 3), problem: (D) Distinct Characters Queries
题目大意
线段树单点修改区间查询
题解
线段树维护二进制,将查询的字母区间内的字母转化为二进制下,合并区间就是与操作,最后我们看我们所查询得到的二进制有几个1即可
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
char s[maxn];
int tree[maxn*4];
int n,q;
inline void PushUp(int rt){
tree[rt]=tree[rt<<1] | tree[rt<<1|1];
}
void build(int rt,int le,int re){
if(le==re){
tree[rt]=1<<(s[le]-'a');
return;
}
int mid=(le+re)/2;
build(rt<<1,le,mid);
build(rt<<1|1,mid+1,re);
PushUp(rt);
}
void Update(int rt,int le,int re,int p,int c){
if(le==re){
tree[rt]=1<<c;
return;
}
int mid=(le+re)/2;
if(p<=mid)
Update(rt<<1,le,mid,p,c);
else
Update(rt<<1|1,mid+1,re,p,c);
PushUp(rt);
}
int Query(int rt,int le,int re,int ql,int qr){
if(qr<le||ql>re)
return 0;
if(ql<=le&&qr>=re)
return tree[rt];
int mid=(le+re)/2;
int res=0;
res |=Query(rt<<1,le,mid,ql,qr);
res |=Query(rt<<1|1,mid+1,re,ql,qr);
return res;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cin>>s+1;
n=strlen(s+1);
build(1,1,n);
cin>>q;
int op,le,re;
char va;
while(q--){
cin>>op;
if(op==1){
cin>>le>>va;
Update(1,1,n,le,va-'a');
}
else{
cin>>le>>re;
int res=Query(1,1,n,le,re);
int cnt=0;
while(res){
if(res&1)
cnt++;
res>>=1;
}
cout<<cnt<<endl;
}
}
return 0;
}
学如逆水行舟,不进则退
掘金搜【一百个Chocolate】座右铭:学如逆水行舟,不进则退!公众号:小狮子前端 期待小狮子们的加入~