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); } } }