1234D.Distinct Characters Queries(树状数组)

你有一个字符串s组成的小写拉丁字母和q查询这个字符串。

 

回想一下,字符串s的子字符串s[l;r]是字符串slsl+1…sr。例如,“codeforce”的子字符串是“code”、“force”、“f”、“For”,而不是“coder”和“top”。

 

有两种查询类型:

 

1 pos c(1≤pos≤|s|, c为小写拉丁字母):将spos替换为c (set spos:=c);

2 l r(1≤l≤r≤|s|):计算子串s[l;r]中不同字符的个数。

 

题解:

开26个树状数组,存储26个字母的前缀和。

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+100;
string s;
int c[26][maxn];
int len;
int lowbit (int x) {
    return x&-x;
}
void update (int id,int x,int val) {
    for (int i=x;i<=len;i+=lowbit(i)) c[id][i]+=val;
}
int getsum (int id,int x) {
    int ans=0;
    for (int i=x;i;i-=lowbit(i)) ans+=c[id][i];
    return ans;
}
int main () {
    cin>>s;
    int N;
    scanf("%d",&N);
    len=s.length();
    for (int i=1;i<=len;i++) 
        update(s[i-1]-'a',i,1);
    for (int i=1;i<=N;i++) {
        int f;
        scanf("%d",&f);
        if (f==1) {
            int x;
            char ch;
            scanf("%d %c",&x,&ch);
            update(s[x-1]-'a',x,-1);
            update(ch-'a',x,1);
            s[x-1]=ch;
        }
        else {
            int l,r;
            scanf("%d%d",&l,&r);
            int ans=0;
            for (int j=0;j<26;j++) {
                if (getsum(j,r)-getsum(j,l-1)>=1) 
                    ans++;
            }
            printf("%d\n",ans);
        }
    }
}

 

posted @ 2020-04-12 20:47  zlc0405  阅读(239)  评论(0编辑  收藏  举报