Codeforces Round #590 (Div. 3) D Distinct Characters Queries(set)

题目链接: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;
}

 

你可能感兴趣的:(STL容器,思维)