把左括号看做$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 }
By Xs酱~ 转载请说明
博客地址:http://www.cnblogs.com/rausen