Codeforces 588E. A Simple Task (线段树+计数排序思想)
题目链接:http://codeforces.com/contest/558/problem/E
题意:有一串字符串,有两个操作:1操作是将l到r的字符串升序排序,0操作是降序排序。
题解:建立26棵线段树,类似计数排序思想。
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N = 1e5 + 5; 4 struct SegTree { 5 int lazy[27], sum[27], l, r; 6 }T[N << 2]; 7 int a[27][N]; 8 9 void pushup(int p, int c) { 10 T[p].sum[c] = T[p << 1].sum[c] + T[(p << 1)|1].sum[c]; 11 } 12 13 void pushdown(int p, int c) { 14 if(T[p].lazy[c] != -1) { 15 T[p << 1].sum[c] = T[p].lazy[c]*(T[p << 1].r - T[p << 1].l + 1); 16 T[(p << 1)|1].sum[c] = T[p].lazy[c]*(T[(p << 1)|1].r - T[(p << 1)|1].l + 1); 17 T[p << 1].lazy[c] = T[(p << 1)|1].lazy[c] = T[p].lazy[c]; 18 T[p].lazy[c] = -1; 19 } 20 } 21 22 void build(int p, int c, int l, int r) { 23 int mid = (l + r) >> 1; 24 T[p].l = l, T[p].r = r, T[p].lazy[c] = -1; 25 if(l == r) { 26 T[p].sum[c] = a[c][l]; 27 return ; 28 } 29 build(p << 1, c, l, mid); 30 build((p << 1)|1, c, mid + 1, r); 31 pushup(p, c); 32 } 33 34 int query(int p, int c, int l, int r) { 35 int mid = (T[p].l + T[p].r) >> 1; 36 if(T[p].l == l && T[p].r == r) { 37 return T[p].sum[c]; 38 } 39 pushdown(p, c); 40 if(r <= mid) { 41 return query(p << 1, c, l, r); 42 } else if(l > mid) { 43 return query((p << 1)|1, c, l, r); 44 } else { 45 return query(p << 1, c, l, mid) + query((p << 1)|1, c, mid + 1, r); 46 } 47 pushup(p, c); 48 } 49 50 void update(int p, int c, int l, int r, int val) { 51 int mid = (T[p].l + T[p].r) >> 1; 52 if(T[p].l == l && T[p].r == r) { 53 T[p].lazy[c] = val; 54 T[p].sum[c] = val * (r - l + 1); 55 return ; 56 } 57 pushdown(p, c); 58 if(r <= mid) { 59 update(p << 1, c, l, r, val); 60 } else if(l > mid) { 61 update((p << 1)|1, c, l, r, val); 62 } else { 63 update(p << 1, c, l, mid, val), update((p << 1)|1, c, mid + 1, r, val); 64 } 65 pushup(p, c); 66 } 67 char str[N]; 68 69 int main() 70 { 71 int n, m; 72 scanf("%d %d", &n, &m); 73 scanf("%s", str); 74 for(int i = 0; i < n; ++i) { 75 a[str[i] - 'a'][i + 1] = 1; 76 } 77 for(int i = 0; i < 26; ++i) { 78 build(1, i, 1, n); 79 } 80 while(m--) { 81 int l, r, c; 82 scanf("%d %d %d", &l, &r, &c); 83 if(c) { 84 int x = l, y = r; 85 for(int i = 0; i < 26; ++i) { 86 if(x > y) 87 break; 88 int num = query(1, i, l, r); 89 if(!num) 90 continue; 91 update(1, i, l, r, 0); 92 update(1, i, x, x + num - 1, 1); 93 x = x + num; 94 } 95 } else { 96 int x = l, y = r; 97 for(int i = 25; i >= 0; --i) { 98 if(x > y) 99 break; 100 int num = query(1, i, l, r); 101 if(!num) 102 continue; 103 update(1, i, l, r, 0); 104 update(1, i, x, x + num - 1, 1); 105 x = x + num; 106 } 107 } 108 } 109 for(int i = 1; i <= n; ++i) { 110 for(int j = 0; j < 26; ++j) { 111 if(query(1, j, i, i)) { 112 putchar(char(j + 'a')); 113 break; 114 } 115 } 116 } 117 putchar('\n'); 118 return 0; 119 }