码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ2329 [HNOI2011]括号修复

时间:2015-05-27 00:56:23      阅读:108      评论:0      收藏:0      [点我收藏+]

标签:

把左括号看做$1$,右括号看做$-1$,于是查询操作等于查询一个区间左边右边最大(最小)子段和

支持区间翻转,反转,覆盖操作。。。注意如果有覆盖操作,之前的操作全部作废了。。。于是在下传标记的时候要最后做。。。

 

技术分享
  1 /**************************************************************
  2     Problem: 2329
  3     User: rausen
  4     Language: C++
  5     Result: Accepted
  6     Time:4252 ms
  7     Memory:7352 kb
  8 ****************************************************************/
  9  
 10 #include <cstdio>
 11 #include <algorithm>
 12  
 13 #define _max(x, y) (x > y ? x : y)
 14 #define _min(x, y) (x < y ? x : y)
 15 using namespace std;
 16 const int N = 1e5 + 5;
 17  
 18 int read();
 19 int get_c();
 20 int get_op();
 21  
 22 namespace treap {
 23     struct node;
 24     node *root, *null;
 25      
 26     struct node {
 27         node *ls, *rs;
 28         int val, rev, inv, fill, maxl, maxr, minl, minr, sum, sz;
 29          
 30         #define Len (1 << 16)
 31         inline void* operator new(size_t, int _v = 0) { 
 32             static node *mempool, *c;
 33             if (mempool == c)
 34                 mempool = (c = new node[Len]) + Len;
 35             c -> ls = c -> rs = null;
 36             c -> val = c -> sum = _v, c -> rev = c -> inv = c -> fill = 0;
 37             c -> maxl = c -> maxr =  c -> minl = c -> minr = 0;
 38             c -> sz = 1;
 39             return c++;
 40         }
 41         #undef Len
 42                  
 43         inline void reverse() {
 44             rev ^= 1;
 45             swap(ls, rs);
 46             swap(minl, minr), swap(maxl, maxr);
 47         }
 48         inline void inverse() {
 49             inv ^= 1;
 50             fill = -fill, val = -val, sum = -sum;
 51             swap(maxl, minl), maxl = -maxl, minl = -minl;
 52             swap(maxr, minr), maxr = -maxr, minr = -minr;
 53         }
 54         inline void replace(int t) {
 55             fill = val = t, sum = sz * t;
 56             maxl = maxr = sz * (t == 1);
 57             minl = minr = -sz * (t == -1);
 58         }
 59  
 60         inline node* update() {
 61             sz = ls -> sz + rs -> sz + 1;
 62             sum = ls -> sum + rs -> sum + val;
 63             maxl = _max(ls -> maxl, ls -> sum + val + _max(0, rs -> maxl));
 64             minl = _min(ls -> minl, ls -> sum + val + _min(0, rs -> minl));
 65             maxr = _max(rs -> maxr, rs -> sum + val + _max(0, ls -> maxr));
 66             minr = _min(rs -> minr, rs -> sum + val + _min(0, ls -> minr));
 67             return this;
 68         }
 69         inline node* push() {
 70             if (rev) {
 71                 ls -> reverse(), rs -> reverse();
 72                 rev = 0;
 73             }
 74             if (inv) {
 75                 ls -> inverse(), rs -> inverse();
 76                 inv = 0; 
 77             }
 78             if (fill) {
 79                 ls -> replace(fill), rs -> replace(fill);
 80                 fill = 0;
 81             }
 82             return this;
 83         }
 84     };
 85      
 86     inline void init() {
 87         null = new()node;
 88         null -> ls = null -> rs = null;   
 89         null -> sz = null -> val = 0;
 90     }
 91      
 92     inline unsigned int Rand() {
 93         static unsigned int res = 2333;
 94         return res += res << 2 | 1;
 95     }
 96     inline int random(int x, int y) {
 97         return Rand() % (x + y) < x;
 98     }
 99      
100     void build(node *&p, int l, int r, int *a) {
101         if (l > r) {
102             p = null;
103             return;
104         }
105         p = new(a[l + r >> 1])node;
106         if (l == r) {
107             p -> update();
108             return;
109         }
110         build(p -> ls, l, (l + r >> 1) - 1, a);
111         build(p -> rs, (l + r >> 1) + 1, r, a);
112         p -> update();
113     }
114      
115     void merge(node *&p, node *x, node *y) {
116         if (x == null || y == null)
117             p = x == null ? y -> push() : x -> push();
118         else if (random(x -> sz, y -> sz)) {
119             p = x -> push();
120             merge(p -> rs, x -> rs, y);
121         } else {
122             p = y -> push();
123             merge(p -> ls, x, y -> ls);
124         }
125         p -> update();
126     }
127      
128     void split(node *p, node *&x, node *&y, int k) {
129         if (!k) {
130             x = null, y = p -> push();
131             return;
132         }
133         if (k == p -> sz) {
134             x = p -> push(), y = null;
135             return;
136         }
137         if (p -> ls -> sz >= k) {
138             y = p -> push();
139             split(p -> ls, x, y -> ls, k);
140             y -> update();
141         } else {
142             x = p -> push();
143             split(p -> rs, x -> rs, y, k - p -> ls -> sz - 1);
144             x -> update();
145         }
146     }
147 }
148 using namespace treap;
149  
150 int n;
151 int a[N];
152  
153 int main() {
154     int Q, i, oper, l, r;
155     node *x, *y, *z;
156     init();
157     n = read(), Q = read();
158     for (i = 1; i <= n; ++i) a[i] = get_c();
159     build(root, 1, n, a);
160     while (Q--) {
161         oper = get_op(), l = read(), r = read();
162         split(root, x, y, l - 1), split(y, y, z, r - l + 1);
163         if (oper == 0) y -> replace(get_c());
164         else if (oper == 1) printf("%d\n", (y -> maxr + 1) / 2 - (y -> minl - 1) / 2);
165         else if (oper == 2) y -> reverse();
166         else if (oper == 3) y -> inverse();
167         merge(root, x, y -> push()), merge(root, root, z);
168     }
169     return 0;
170 }
171  
172 inline int read() {
173     register int x = 0;
174     register char ch = getchar();
175     while (ch < 0 || 9 < ch) ch = getchar();
176     while (0 <= ch && ch <= 9)
177         x = x * 10 + ch - 0, ch = getchar();
178     return x;
179 }
180  
181 inline int get_c() {
182     register char ch = getchar();
183     while (ch != ( && ch != )) ch = getchar();
184     return ch == ( ? 1 : -1;
185 }
186  
187 inline int get_op() {
188     register char ch = getchar();
189     while (ch != R && ch != Q && ch != S && ch != I) ch = getchar();
190     if (ch == R) return 0;
191     if (ch == Q) return 1;
192     if (ch == S) return 2;
193     if (ch == I) return 3;
194 }
View Code

 

BZOJ2329 [HNOI2011]括号修复

标签:

原文地址:http://www.cnblogs.com/rausen/p/4532055.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!