• UPC-Simple String Queries(二维树状数组)


    你的偶像光芒万丈,你不能一身戾气。

    Simple String Queries

    You are given a string S of length N consisting of lowercase English letters.
    Process Q queries of the following two types:
    Type 1: change the iq-th character of S to cq. (Do nothing if the iq-th character is already cq.)
    Type 2: answer the number of different characters occurring in the substring of S between the lq-th and rq-th characters (inclusive).

    Constraints
    ·N, Q, iq, lq, and rq are integers.
    ·S is a string consisting of lowercase English letters.
    ·cq is a lowercase English letter.
    ·1≤N≤500000
    ·1≤Q≤20000
    ·|S|=N
    ·1≤iq≤N
    ·1≤lq≤rq≤N
    ·There is at least one query of type 2 in each testcase.
    输入
    Input is given from Standard Input in the following format:
    N
    S
    Q
    Query1

    QueryQ
    Here,Queryi in the 4-th through (Q+3)-th lines is one of the following:
    1 iq cq
    2 lq rq
    输出
    For each query of type 2, print a line containing the answer.

    样例输入 Copy
    7
    abcdbbd
    6
    2 3 6
    1 5 z
    2 1 1
    1 4 a
    1 7 d
    2 1 7
    样例输出 Copy
    3
    1
    5
    提示
    In the first query, cdbb contains three kinds of letters: b , c , and d, so we print 3.
    In the second query, S is modified to abcdzbd.
    In the third query, a contains one kind of letter: a, so we print 1.
    In the fourth query, S is modified to abcazbd.
    In the fifth query, S does not change and is still abcazbd.
    In the sixth query, abcazbd contains five kinds of letters: a, b, c, d, and z, so we print 5.

    题意: 给你一个字符串和若干次操作,操作1是更改字符串里的一个字母,操作2是查询该区间里不同字母的数量。要求输出操作2的查询结果。
    思路: 裸的树状数组的单点修改和区间查询,我们用一个二维数组记录每个字母在此之前出现的次数,然后按照树状数组的思路写就可以了。
    本题要注意:数组要开到5e5+10左右。每次更改时要把之前的字母删去。每次更改时要修改字符串里的字母。
    代码:

    #include<iostream>
    using namespace std;
    int n,m;
    int tr[26][500010];
    int lowbit(int x){
        return x&-x;
    }
    void add(int i,int x,int y){
        for(int j=i;j<=n;j+=lowbit(j))
            tr[x][j]+=y;
    }
    int ask(int x,int y){
        int res=0;
            for(int j=x;j;j-=lowbit(j))
                res+=tr[y][j];
        return res;
    }
    char s[500010];
    int main(){
        cin>>n;
        cin>>s+1;
        for(int i=1;i<=n;i++){
            int x=s[i]-'a';
            add(i,x,1);
        }
        cin>>m;
        while(m--){
            int a,b,c;char ch;
            cin>>a;
            if(a==1){
                cin>>b>>ch;
                c=ch-'a';
                add(b,s[b]-'a',-1);
                add(b,c,1);
                s[b]=ch;
            }
            else{
                int res=0;
                cin>>b>>c;
                for(int i=0;i<26;i++){
                    int sum=ask(c,i)-ask(b-1,i);
                    if(sum>0) res++;
                }
                cout<<res<<endl;
            }
        }
        return 0;
    }
    
  • 相关阅读:
    Python3之random模块常用方法
    Go语言学习笔记(九)之数组
    Go语言学习笔记之简单的几个排序
    Go语言学习笔记(八)
    Python3之logging模块
    Go语言学习笔记(六)
    123. Best Time to Buy and Sell Stock III(js)
    122. Best Time to Buy and Sell Stock II(js)
    121. Best Time to Buy and Sell Stock(js)
    120. Triangle(js)
  • 原文地址:https://www.cnblogs.com/OvOq/p/14853190.html
Copyright © 2020-2023  润新知