[BZOJ2209][[Jsoi2011]括号序列][splay]
2017-03-11 15:53
417 查看
[BZOJ2209][[Jsoi2011]括号序列][splay]
题目大意:
给定一个长度为N的括号序列,有三种操作:询问让A[x],a[x+1],...,a[y]这个括号序列合法至少需要修改几个括号。
将A[x],a[x+1],...,a[y]翻转
将A[x],a[x+1],...,a[y]反转(左右括号互换)
思路:
去除已经匹配的括号后,剩下的括号一定是左边剩下x个左括号,右边剩下y个右括号且x,y奇偶性相同。比如下面这个括号序列。))()()())()(
删除已经匹配好的就变成:
)))(,x=3,y=1
这时候的答案是:
{x/2+y/2x/2+1+y/2+1x,y%2=0x,y%2=1
也就是(x+1)/2+(y+1)/2。
对于序列(l,r),x是左端点为l,右端点<=r时,序列中右括号比左括号多的个数的最大值(>=0)。当将”(=1”,”)=−1”时,实际上求的就是最小左字段和,而y求的则是最大右字段和。注意到题目中有反转的操作,因此最大左字段和和最小右字段和也应当保存下来。
序列可以用splay+lazy标志维护。
代码:
#include <bits/stdc++.h> const int Maxn = 110005; using namespace std; namespace IO { inline char get(void) { static char buf[1000000], *p1 = buf, *p2 = buf; if (p1 == p2) { p2 = (p1 = buf) + fread(buf, 1, 1000000, stdin); if (p1 == p2) return EOF; } return *p1++; } inline void read(int &x) { x = 0; static char c; bool f = 0; for (; !(c >= '0' && c <= '9'); c = get()) if (c == '-') f = 1; for (; c >= '0' && c <= '9'; x = x * 10 + c - '0', c = get()); if (f) x = -x; } inline void read(char &x) { x = get(); while (x != '(' && x != ')') x = get(); } inline void write(int x) { if (!x) return (void)puts("0"); if (x < 0) putchar('-'), x = -x; static short s[12], t; while (x) s[++t] = x % 10, x /= 10; while (t) putchar('0' + s[t--]); putchar('\n'); } }; int n, m; int c[Maxn][2], fa[Maxn], sum[Maxn], sz[Maxn], a[Maxn], rt; bool rev[Maxn], opp[Maxn]; struct Val { int l0, l1, r0, r1; } val[Maxn]; inline int Min(const int &a, const int &b) { return a < b ? a : b; } inline int Max(const int &a, const int &b) { return a > b ? a : b; } inline void pushUp(int x) { int l = c[x][0], r = c[x][1]; sum[x] = sum[l] + sum[r] + a[x]; sz[x] = sz[l] + sz[r] + 1; val[x].l0 = Min(val[l].l0, sum[l] + a[x] + val[r].l0); val[x].l1 = Max(val[l].l1, sum[l] + a[x] + val[r].l1); val[x].r0 = Min(val[r].r0, sum[r] + a[x] + val[l].r0); val[x].r1 = Max(val[r].r1, sum[r] + a[x] + val[l].r1); } inline void rever(int x) { rev[x] ^= 1; swap(val[x].l0, val[x].r0); swap(val[x].l1, val[x].r1); } inline void opposite(int x) { opp[x] ^= 1; sum[x] = -sum[x]; a[x] = -a[x]; swap(val[x].l0, val[x].l1); swap(val[x].r0, val[x].r1); val[x].l0 = -val[x].l0, val[x].l1 = -val[x].l1; val[x].r0 = -val[x].r0, val[x].r1 = -val[x].r1; } inline void pushDown(int x) { if (rev[x]) { rever(c[x][0]), rever(c[x][1]); swap(c[x][0], c[x][1]); rev[x] = 0; } if (opp[x]) { opposite(c[x][0]), opposite(c[x][1]); opp[x] = 0; } } inline void rotate(int x, int &k) { int y = fa[x], z = fa[y], r = (x == c[y][0]); y == k ? k = x : c[z][!(c[z][0] == y)] = x; fa[x] = z; fa[y] = x; fa[c[x][r]] = y; c[y][r ^ 1] = c[x][r]; c[x][r] = y; pushUp(y), pushUp(x); } inline void splay(int x, int &k) { while (x != k) { int y = fa[x], z = fa[y]; if (y != k) { if ((c[y][0] == x) ^ (c[z][0] == y)) rotate(x, k); else rotate(y, k); } rotate(x, k); } } void build(int &k, int l, int r, int last) { if (l > r) return (void)(k = 0); k = (l + r) >> 1; fa[k] = last; if (l == r) { sum[k] = a[l]; sz[k] = 1; if (a[l] < 0) val[k].l0 = val[k].r0 = -1; if (a[l] > 0) val[k].l1 = val[k].r1 = 1; return; } build(c[k][0], l, k - 1, k), build(c[k][1], k + 1, r, k); pushUp(k); } inline int find(int x, int tar) { pushDown(x); int l = c[x][0], r = c[x][1]; if (tar == sz[l] + 1) return x; else if (tar <= sz[l]) return find(l, tar); else return find(r, tar - sz[l] - 1); } int main(void) { //freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout); IO::read(n), IO::read(m); char op; int t, l, r; for (int i = 2; i <= n + 1; i++) IO::read(op), a[i] = (op == '(' ? 1 : -1); build(rt, 1, n + 2, 0); while (m--) { IO::read(t), IO::read(l), IO::read(r); l = find(rt, l); r = find(rt, r + 2); splay(l, rt); splay(r, c[l][1]); int k = c[r][0]; if (!t) IO::write((val[k].r1 + 1) / 2 - (val[k].l0 - 1) / 2); else if (t == 1) opposite(k); else rever(k); } return 0; }
完。
By g1n0st
相关文章推荐
- 【BZOJ2329/2209】[HNOI2011]括号修复/[Jsoi2011]括号序列 Splay
- bzoj2209 [Jsoi2011]括号序列(splay)
- [BZOJ2209][JSOI2011]括号序列(splay)
- BZOJ 2209: [Jsoi2011]括号序列 [splay 括号]
- bzoj 2209: [Jsoi2011]括号序列 splay
- 【BZOJ】2209: [Jsoi2011]括号序列(splay)
- 【BZOJ2209】括号序列(JSOI2011)-Splay
- bzoj 2209: [Jsoi2011]括号序列(splay)
- bzoj2209: [Jsoi2011]括号序列
- BZOJ2209 [Jsoi2011]括号序列
- BZOJ 2209: [Jsoi2011]括号序列&&BZOJ 2329: [HNOI2011]括号修复
- bzoj2209[Jsoi2011] 括号序列
- BZOJ 2209 [Jsoi2011] 括号序列
- ●BZOJ 2209 [Jsoi2011]括号序列
- BZOJ 2209 括号序列(splay)
- 【BZOJ-2329&2209】括号修复&括号序列 Splay
- bzoj2209括号序列splay
- BZOJ P2209:[Jsoi2011]括号序列
- 【bzoj2329】[HNOI2011]括号修复 Splay
- 【bzoj2329】[HNOI2011]括号修复 splay