codeforce452DIV2——F. Letters Removing

题意:
给一个字符串和m个操作,每次给出l,r,c,把字符串中l-r这段区间的字符为c的字符删掉,求最后的字符串。(n,m<=2e5)
线段树。注意这个区间修改和普通区间修改的区别。

他们都是用树状数组做的哎,可是我对树状数组一直是一脸懵逼

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <iostream>
 5 using namespace std;
 6 const int maxn=200000+100;
 7 const int maxnode=65;
 8 int n,m;
 9 char s[maxn];
10 int a[maxn];
11 int get(char c){
12     if(c>='A'&&c<='Z')return c-'A';
13     if(c>='a'&&c<='z')return c-'a'+26;
14     if(c>='0'&&c<='9')return c-'0'+52;
15 }
16 char res(int x){
17     if(x>=0&&x<26)return x+'A';
18     if(x>=26&&x<52)return x-26+'a';
19     if(x>=52&&x<62)return x-52+'0';
20 }
21 int sumv[4*maxn],num[4*maxn][maxnode];
22 void build(int o,int L,int R){
23     if(L==R){
24         sumv[o]=1;
25         num[o][a[L]]=1;
26         return ;
27     }
28     int M=L+(R-L)/2;
29     build(2*o,L,M);
30     build(2*o+1,M+1,R);
31     sumv[o]=sumv[2*o]+sumv[2*o+1];
32     for(int i=0;i<62;i++)
33         num[o][i]=num[2*o][i]+num[2*o+1][i];
34 }
35 int ql,qr,c;
36 void update(int o,int L,int R){
37     if(num[o][c]==0)return ;
38     if(ql>R||qr<L)
39         return ;
40     if(L==R){
41         if(num[o][c]){
42         sumv[o]=0;
43         num[o][c]=0;
44         }
45         return ;
46     }
47     int M=L+(R-L)/2;
48     update(2*o,L,M);
49     update(2*o+1,M+1,R);
50     sumv[o]=sumv[2*o]+sumv[2*o+1];
51     num[o][c]=num[2*o][c]+num[2*o+1][c];
52 }
53 int find(int o,int L,int R ,int k){
54     int M=L+(R-L)/2;
55     if(L==R)return L;
56     if(sumv[2*o]>=k)return find(2*o,L,M,k);
57     else return find(2*o+1,M+1,R,k-sumv[2*o]);
58 }
59 void tra(int o,int L,int R){
60     if(sumv[o]==0)return ;
61     if(L==R){
62         for(int i=0;i<62;i++)
63         if(num[o][i]){
64             int c=res(i);
65             printf("%c",c);
66         }
67         return ;
68     }
69     int M=L+(R-L)/2;
70     tra(2*o,L,M);
71     tra(2*o+1,M+1,R);
72 }
73 int main(){
74     scanf("%d%d",&n,&m);
75     scanf("%s",s+1);
76     for(int i=1;i<=n;i++)a[i]=get(s[i]);
77     build(1,1,n);
78     int L,R;
79     char cc;
80     for(int i=1;i<=m;i++){
81         scanf("%d%d %c",&L,&R,&cc);
82         L=find(1,1,n,L),R=find(1,1,n,R);
83         ql=L,qr=R,c=get(cc);
84         update(1,1,n);
85     }
86     tra(1,1,n);
87 return 0;
88 }
View Code
原文地址:https://www.cnblogs.com/LQLlulu/p/8785728.html