题目链接:https://codeforces.com/contest/1234/problem/D
题目大意:给一个字符串,俩操作,一个是把pos位上的字母改成c,一个是求l到r内不同字母个数
题目思路:第一眼:我擦带修主席树,凉凉不会,就放弃了,看到题解就很难受。一共就26个字母,直接来26个set维护每个字母的位置就行了。。同理可以用树状数组
还有个很骚的办法,用线段树,一个数字二进制为1的位置表示这个区间内有这个字母,合并直接或就行
以后不能被认知偏见局限,勇于挑战!
以下是代码:
#include
using namespace std;
#define inf 0x3f3f3f3f
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
#define ll long long
const int MAXN = 2e5+5;
const int MOD =1e9+7;
char t[MAXN],p[MAXN];
int n,a,b;
sets[30];
int main(){
while(~scanf("%s",t+1)){
rep(i,0,25)s[i].clear();
int len=strlen(t+1);
rep(i,1,len){
s[t[i]-'a'].insert(i);
}
scanf("%d",&n);
rep(i,1,n){
scanf("%d",&a);
if(a==1){
scanf("%d%s",&b,p);
s[t[b]-'a'].erase(b);
t[b]=p[0];
s[p[0]-'a'].insert(b);
}
else{
int ans=0;
scanf("%d%d",&a,&b);
rep(i,0,25){
set::iterator it=s[i].lower_bound(a);
if(it==s[i].end()||*it>b)continue;
ans++;
}
printf("%d\n",ans);
}
}
}
return 0;
}