你的偶像光芒万丈,你不能一身戾气。
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; }