【线段树-区间更新】codeforces 558e A Simple Task

通道:http://codeforces.com/contest/558/problem/e

题意:给出一个字符串,Q个询问,(l,r,v),将[l,r]区间升序或降序排序(v==0|v==1)

思路:26颗线段树,区间更新即可。

代码:

  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 }
View Code

 

posted @ 2015-07-15 12:25  mithrilhan  阅读(189)  评论(0编辑  收藏  举报