YYHS-string(线段树)

   

题解

这道题给你两个操作,一个升序,一个降序

我们可以观察到这个字符串都是由小写字母组成的,只有26个字符,所以我们开一个26个字符的线段树

每次查询的时候找到这个区间内‘a'到'z'的数量,再判断一下要升序还是降序就可以喽

 1 #include<bits/stdc++.h>
 2 #define L 100005 
 3 using namespace std;
 4 int n,m,l,r,x;
 5 int mark[4*L][26],tree[4*L][26];
 6 char s[L];
 7 void build(int v,int l,int r){
 8     if (l==r){
 9         tree[v][s[l]-'a']=1;
10         return;
11     }
12     int mid=(l+r)>>1;
13     build(v<<1,l,mid);
14     build(v<<1|1,mid+1,r);
15     for (int i=0;i<26;i++)
16         tree[v][i]=tree[v<<1][i]+tree[v<<1|1][i];
17 }
18 void pushdown(int v,int k,int l,int r){
19     int mid=(l+r)>>1;
20     if (mark[v][k]){
21         mark[v<<1][k]=mark[v][k];
22         mark[v<<1|1][k]=mark[v][k];
23         if (mark[v][k]&1)
24             tree[v<<1][k]=tree[v<<1|1][k]=0;
25         else{
26             tree[v<<1][k]=mid-l+1;
27             tree[v<<1|1][k]=r-mid;
28         }
29         mark[v][k]=0;
30     }
31 }
32 void change(int v,int l,int r,int x,int y,int k,int key){
33     if (mark[v][k]==key+1) return;
34     if (x<=l&&y>=r){
35         mark[v][k]=key+1;
36         if (!key) tree[v][k]=0;
37                 else tree[v][k]=r-l+1;
38         return;
39     }
40     pushdown(v,k,l,r);
41     int mid=(l+r)>>1;
42     if (y<=mid) change(v<<1,l,mid,x,y,k,key); else
43     if (x>mid) change(v<<1|1,mid+1,r,x,y,k,key);
44     else{
45         change(v<<1,l,mid,x,mid,k,key);
46         change(v<<1|1,mid+1,r,mid+1,y,k,key);
47     }
48     tree[v][k]=tree[v<<1][k]+tree[v<<1|1][k];
49 }
50 int query(int v,int l,int r,int x,int y,int k){
51     if (!tree[v][k]) return 0;
52     if (x<=l&&y>=r) return tree[v][k];
53     pushdown(v,k,l,r);
54     int mid=(l+r)>>1;
55     if (y<=mid) return query(v<<1,l,mid,x,y,k); else
56     if (x>mid) return query(v<<1|1,mid+1,r,x,y,k); else
57     return query(v<<1,l,mid,x,mid,k)+query(v<<1|1,mid+1,r,mid+1,y,k);
58 }
59 int main(){
60     scanf("%d%d",&n,&m);
61     scanf("%s",s+1);
62     build(1,1,n);
63     for (int i=1;i<=m;i++){
64         scanf("%d%d%d",&l,&r,&x);
65         int now=l;
66         if (x){
67             for (int j=0;j<26;j++){
68                 int t=query(1,1,n,l,r,j);
69                 if (!t) continue;
70                 change(1,1,n,l,r,j,0);
71                 change(1,1,n,now,now+t-1,j,1);
72                 now+=t;
73             }
74         } else{
75             for (int j=25;j>=0;j--){
76                 int t=query(1,1,n,l,r,j);
77                 if (!t) continue;
78                 change(1,1,n,l,r,j,0);
79                 change(1,1,n,now,now+t-1,j,1);
80                 now+=t;
81             }
82         }
83     }
84     for (int i=1;i<=n;i++)
85         for (int j=0;j<26;j++)
86             if (query(1,1,n,i,i,j)){
87                 printf("%c",j+'a');
88                 break;
89             }
90     return 0;
91 }
View Code

 

posted @ 2017-10-20 12:50  I__am  阅读(262)  评论(0编辑  收藏  举报