【线段树-区间更新】codeforces 558e A Simple Task
通道:http://codeforces.com/contest/558/problem/e
题意:给出一个字符串,Q个询问,(l,r,v),将[l,r]区间升序或降序排序(v==0|v==1)
思路:26颗线段树,区间更新即可。
代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <cstdio> 2 #include <cstring> 3 4 const int MAX_N = 100001; 5 6 #define lson idx << 1 7 #define rson idx << 1 | 1 8 9 struct Node { 10 int l, r; 11 int set, sum; 12 Node() { 13 14 } 15 Node (int _l, int _r, int _s, int _ss) { 16 l = _l, r = _r, set = _s, sum = _ss; 17 } 18 }; 19 20 int n, q; 21 char str[MAX_N]; 22 23 struct Segment { 24 Node tree[MAX_N << 2]; 25 void up(int idx) { 26 tree[idx].sum = tree[lson].sum + tree[rson].sum; 27 } 28 void down(int idx) { 29 if (~tree[idx].set) { 30 tree[lson].set = tree[rson].set = tree[idx].set; 31 tree[lson].sum = tree[idx].set * (tree[lson].r - tree[lson].l + 1); 32 tree[rson].sum = tree[idx].set * (tree[rson].r - tree[rson].l + 1); 33 tree[idx].set = -1; 34 } 35 } 36 void build(int idx, int l, int r, int seg) { 37 tree[idx] = Node(l, r, -1, 0); 38 if (l == r) { 39 tree[idx].sum = str[l] == 'a' + seg; 40 return ; 41 } 42 int mid = l + r >> 1; 43 build(lson, l, mid, seg); 44 build(rson, mid + 1, r, seg); 45 up(idx); 46 } 47 void update(int y1, int y2, int idx, int val) { 48 if (tree[idx].l == y1 && tree[idx].r == y2) { 49 tree[idx].set = val; 50 tree[idx].sum = val * (tree[idx].r - tree[idx].l + 1); 51 return ; 52 } 53 down(idx); 54 int mid = tree[idx].l + tree[idx].r >> 1; 55 if (y2 <= mid) update(y1, y2, lson, val); 56 else if (y1 > mid) update(y1, y2, rson, val); 57 else { 58 update(y1, mid, lson, val); 59 update(mid+1, y2, rson, val); 60 } 61 up(idx); 62 } 63 int query(int y1, int y2, int idx) { 64 if (tree[idx].l == y1 && tree[idx].r == y2) 65 return tree[idx].sum; 66 down(idx); 67 int mid = (tree[idx].l + tree[idx].r) >> 1; 68 if (y2 <= mid) return query(y1, y2, lson); 69 else if (y1 > mid) return query(y1, y2, rson); 70 else return query(y1, mid, lson) + query(mid+1, y2, rson); 71 } 72 } Seg[27]; 73 74 int now[27]; 75 76 int main() { 77 scanf("%d%d%s", &n, &q, str + 1); 78 for (int i = 0; i < 26; ++i) Seg[i].build(1, 1, n, i); 79 for (int i = 0; i < q; ++i) { 80 int l, r, v; 81 scanf("%d%d%d", &l, &r, &v); 82 for (int j = 0; j < 26; ++j) { 83 now[j] = Seg[j].query(l, r, 1); 84 Seg[j].update(l, r, 1, 0); 85 } 86 if (v == 1) { 87 for (int j = 0; j < 26; ++j) { 88 if (now[j]) Seg[j].update(l, l + now[j] - 1, 1, 1); 89 l += now[j]; 90 } 91 } else { 92 for (int j = 25; j >= 0; --j) { 93 if (now[j]) Seg[j].update(l, l + now[j] - 1, 1, 1); 94 l += now[j]; 95 } 96 } 97 } 98 for (int i = 1; i <= n; ++i) 99 for (int j = 0; j < 26; ++j) { 100 if (Seg[j].query(i, i, 1)) { 101 putchar('a' + j); 102 break; 103 } 104 } 105 return 0; 106 }