Codeforces #590 D 二维树状数组

题意

给一个10^5之内的字符串(小写字母)时限2s

输入n,有n个操作  (n<10^5)

当操作是1的时候,输入位置x和改变的字母

当操作是2的时候,输入区间l和r,有多少不同的字母

思路

二维树状数组

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<map>
#define lowbit(x) x&(-x)
using namespace std;
const int maxn=1e5+10;
char s[maxn];
int l,n,yi,er,san;
char c;
struct node{
    int tr[maxn];
    void inint(){
        memset(tr,0,sizeof(tr));
    }
    void updata(int x,int y){
        for(int i=x; i<=l; i+=lowbit(i)){
            tr[i]+=y;
        }
    }
    int geshu(int x,int y){
        int sum1=0,sum2=0;
        for(int i=x; i>0; i-=lowbit(i)){
            sum1+=tr[i];
        }
        for(int i=y; i>0; i-=lowbit(i)){
            sum2+=tr[i];
        }
        return sum2-sum1;
    }
} a[27];
int main(){

    while(~scanf("%s",&s)){
        for(int i=0; i<26; i++){
            a[i].inint();
        }
        l=strlen(s);
        for(int i=0; i<l; i++){
            a[s[i]-'a'].updata(i+1,1);
        }
        scanf("%d",&n);
        for(int i=0; i<n; i++){
            scanf("%d",&yi);
            if(yi==1){
                scanf("%d %c",&er,&c);
                er--;
                a[s[er]-'a'].updata(er+1,-1);
                s[er]=c;
                a[s[er]-'a'].updata(er+1,1);

            }
            else{
                scanf("%d%d",&er,&san);
                int ans=0;
                er--;
                for(int i=0; i<26; i++){
                    //cout<<i<<" "<<a[i].geshu(er,san)<<endl;
                    if(a[i].geshu(er,san)){
                        ans+=1;
                    }
                }
                printf("%d
",ans);
            }
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/luoyugongxi/p/12190090.html