题目链接:https://codeforces.com/contest/1234/problem/D
题目大意:
对于给定的字符串,给出n个查询,查询时输入3个数啊,a,b,c,如果说a==1,则将位置b上的元素变为c,如果数a==2,则输出b到c之间有多少种字母;
这个题目写了好久,正解好像是用树状数组(第一次听说)。 不过还可以用set来写;
用set开的二维数组,也是从小到大排序好的,更骚的操作是可以直接用erase即想要删除a只要s.erase(a)就可以了。
set还支持二分查找,找到的返回地址,找不到返回的是end。。。。。
AC代码:
#include<bits/stdc++.h> using namespace std; set<int >se[30]; set<int >::iterator it; char s[100000+2]; void solve(){ cin>>s+1; int x=strlen(s+1); for(int i=1;i<=x;i++){ se[s[i]-'a'].insert(i); } int n; cin>>n; while(n--){ int t; cin>>t; if(t==1){ int a; char x; cin>>a>>x; se[s[a]-'a'].erase(a); se[x-'a'].insert(a); s[a]=x; } else { int sum=0; int l,r; cin>>l>>r; for(int i=0;i<26;i++){ it=se[i].lower_bound(l); if(it!=se[i].end() && *it<=r) sum++; } cout<<sum<<endl; } } } int main(){ ios::sync_with_stdio(false); solve(); return 0; }