把括号序列后一定是))))((((这种形式的..所以维护一个最大前缀和l, 最大后缀和r就可以了..答案就是(l+1)/2+(r+1)/2...用splay维护,O(NlogN). 其实还是挺好写的, 只是我傻X

--------------------------------------------------------------------------------

#include<cstdio>
#include<algorithm>
#include<cstring>
 
using namespace std;
 
const int maxn = 100009;
 
struct Node* Null;
 
struct Node {
Node *p, *ch[2];
int s, v;
int lmn, lmx, rmn, rmx, sm;
int tg;// tg 1) -1(
bool rev, inv;
inline void Clr() {
lmn = lmx = rmn = rmx = sm = s = v = tg = rev = inv = 0;
}
inline bool d() {
return this == p->ch[1];
}
inline void setc(Node* t, int c) {
ch[c] = t;
t->p = this;
}
inline void Tg(int v) {
tg = v;
rev = inv = false;
}
inline void Rev() {
rev ^= 1;
}
inline void Inv() {
inv ^= 1;
}
inline void pushDown() {
if(tg) {
v = tg;
for(int i = 0; i < 2; i++)
if(ch[i] != Null) ch[i]->Tg(tg);
tg = 0;
}
if(rev) {
swap(ch[0], ch[1]);
for(int i = 0; i < 2; i++)
if(ch[i] != Null) ch[i]->Rev();
rev = false;
}
if(inv) {
v = -v;
for(int i = 0; i < 2; i++)
if(ch[i] != Null) ch[i]->Inv();
inv = false;
}
for(int i = 0; i < 2; i++)
if(ch[i] != Null) ch[i]->upd();
}
inline void upd() {
lmx = max(ch[0]->lmx, ch[0]->sm + max(0, v + max(0, ch[1]->lmx)));
rmx = max(ch[1]->rmx, ch[1]->sm + max(0, v + max(0, ch[0]->rmx)));
lmn = min(ch[0]->lmn, ch[0]->sm + min(0, v + min(0, ch[1]->lmn)));
rmn = min(ch[1]->rmn, ch[1]->sm + min(0, v + min(0, ch[0]->rmn)));
sm = ch[0]->sm + v + ch[1]->sm;
s = ch[0]->s + 1 + ch[1]->s;
if(tg) {
sm = tg * s;
lmx = max(0, sm);
rmx = max(0, sm);
lmn = min(0, sm);
rmn = min(0, sm);
}
if(inv) {
swap(lmn, lmx); lmn = -lmn; lmx = -lmx;
swap(rmn, rmx); rmn = -rmn; rmx = -rmx;
sm = -sm;
}
if(rev) {
swap(lmx, rmx);
swap(lmn, rmn);
}
}
inline int Query() {
return (lmx + 1) / 2 + (-rmn + 1) / 2;
}
} *Root, pool[maxn], *pt;
 
void InitSplay() {
pt = pool;
Root = Null = pt++;
Null->Clr();
Null->setc(Null, 0);
Null->setc(Null, 1);
}
 
Node* NewNode(int v) {
pt->Clr();
pt->v = v;
pt->s = 1;
pt->p = Null;
return pt++;
}
 
void Rot(Node* t) {
Node* p = t->p;
p->pushDown();
t->pushDown();
int d = t->d();
p->p->setc(t, p->d());
p->setc(t->ch[d ^ 1], d);
t->setc(p, d ^ 1);
p->upd();
if(p == Root)
Root = t;
}
 
Node* Select(int k) {
for(Node* t = Root; ; ) {
t->pushDown();
int s = t->ch[0]->s;
if(k == s)
return t;
if(k > s)
k -= s + 1, t = t->ch[1];
else
t = t->ch[0];
}
}
 
void Splay(Node* t, Node* f = Null) {
for(Node* p = t->p; p != f; p = t->p) {
if(p->p != f)
t->d() != p->d() ? Rot(t) : Rot(p);
Rot(t);
}
t->upd();
}
 
Node* Range(int l, int r) {
Splay(Select(--l));
Splay(Select(++r), Root);
return Root->ch[1]->ch[0];
}
 
int N;
char s[maxn];
 
Node* Build(int l, int r) {
if(l >= r)
return Null;
int m = (l + r) >> 1;
Node* t = NewNode(s[m] != ')' ? -1 : 1);
t->setc(Build(l, m), 0);
t->setc(Build(m + 1, r), 1);
t->upd();
return t;
}
 
int main() {
InitSplay();
int m;
scanf("%d%d", &N, &m);
scanf("%s", s + 1);
Root = Build(0, N + 2);
while(m--) {
int l, r;
scanf("%s%d%d", s, &l, &r);
Node* t = Range(l, r);
if(s[0] == 'R') {
char c;
scanf(" %c", &c);
t->Tg(c != '(' ? 1 : -1);
} else if(s[0] == 'S') {
t->Rev();
} else if(s[0] == 'I') {
t->Inv();
} else
printf("%d\n", t->Query());
Splay(t);
}
return 0;
}

--------------------------------------------------------------------------------

2329: [HNOI2011]括号修复

Time Limit: 40 Sec  Memory Limit: 128 MB
Submit: 798  Solved: 368
[Submit][Status][Discuss]

Description

Input

Output

Sample Input

Sample Output

HINT

Source

BZOJ 2329: [HNOI2011]括号修复( splay )的更多相关文章

  1. BZOJ 2329: [HNOI2011]括号修复 [splay 括号]

    题目描述 一个合法的括号序列是这样定义的: 空串是合法的. 如果字符串 S 是合法的,则(S)也是合法的. 如果字符串 A 和 B 是合法的,则 AB 也是合法的. 现在给你一个长度为 N 的由‘(' ...

  2. ●BZOJ 2329 [HNOI2011]括号修复.cpp

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=2329 题解: Splay 类似 BZOJ 2329 [HNOI2011]括号修复 只是多了一 ...

  3. 【BZOJ】2329: [HNOI2011]括号修复(splay+特殊的技巧)

    http://www.lydsy.com/JudgeOnline/problem.php?id=2329 和前一题一样,不就多了个replace操作吗.好,就打一下. 然后交上去wa了........ ...

  4. BZOJ 2329/2209 [HNOI2011]括号修复 (splay)

    题目大意: 让你维护一个括号序列,支持 1.区间修改为同一种括号 2.区间内所有括号都反转 3.翻转整个区间,括号的方向不变 4.查询把某段区间变为合法的括号序列,至少需要修改多少次括号 给跪了,足足 ...

  5. 2329: [HNOI2011]括号修复 - BZOJ

    恶心的splay,打标记的时候还有冲突,要特别小心 上次写完了,查了半天没查出错来,于是放弃 今天对着标程打代码,终于抄完了,我已经不想再写了 const maxn=; type node=recor ...

  6. BZOJ2329 HNOI2011 括号修复 splay+贪心

    找平衡树练习题的时候发现了这道神题,可以说这道题是近几年单考splay的巅峰之作了. 题目大意:给出括号序列,实现区间翻转,区间反转和区间更改.查询区间最少要用几次才能改成合法序列. 分析: 首先我们 ...

  7. 【bzoj2329】[HNOI2011]括号修复 Splay

    题目描述 题解 Splay 由于有区间反转操作,因此考虑Splay. 考虑答案:缩完括号序列后剩下的一定是 $a$ 个')'+ $b$ 个'(',容易发现答案等于 $\lceil\frac a2\rc ...

  8. BZOJ2329: [HNOI2011]括号修复(Splay)

    解题思路: Replace.Swap.Invert都可以使用Splay完美解决(只需要解决一下标记冲突就好了). 最后只需要统计左右括号冲突就好了. 相当于动态统计最大前缀合和最小后缀和. 因为支持翻 ...

  9. 2329: [HNOI2011]括号修复

    传送魔法 一开始以为可以直接线段树的,好像还是不行……还是得用Spaly,然后就没啥了. #include<cstdio> #include<algorithm> #defin ...

随机推荐

  1. git配置别名

    配置别名   有没有经常敲错命令?比如git status?status这个单词真心不好记. 如果敲git st就表示git status那就简单多了,当然这种偷懒的办法我们是极力赞成的. 我们只需要 ...

  2. iOS6和iOS7代码的适配(3)——坐标适配

    由于iOS7里面status bar和视图是重叠在一起了,所以应用的y坐标就没法和以前一致了,需要重新计算设定.基本上,你的应用用Xcode5运行一下就能看见这个问题,这里写了一个最简单的例子,一个V ...

  3. 如何在XML 加入特殊字符内容 如< >

    XML 文件本身包含了一些预定义的保留字符 如< 标记元素的开始符号等 如果要在属性或者元素的值里面包含类似的这些特殊字符 应该如何处理呢 ? 这时候要用到  <![CDATA[] 这个标 ...

  4. Sequence operation(线段树区间多种操作)

    Sequence operation Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  5. Billboard(线段树)

    Billboard Time Limit: 20000/8000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  6. 布线问题(prime)

    布线问题 时间限制:1000 ms  |  内存限制:65535 KB 难度:4   描述 南阳理工学院要进行用电线路改造,现在校长要求设计师设计出一种布线方式,该布线方式需要满足以下条件:1.把所有 ...

  7. Neo4j数据库简单

    作为世界上先进的地图数据库,Neo4j如今,公司已成为许多互联网的首选.Neo4j它是基于java开源地图数据库开发,另外一个NoSQL数据库.Neo4j在保证对数据关系的良好刻画的同一时候.还支持传 ...

  8. hdu-5082

    题意非常easy,就是给出父母的名字,然后依据父母的名字来给孩纸取名字! 能够将此题简化为: 孩纸的名字=父亲的frist name+字符串(_small_)+母亲额frist name; 然后将孩纸 ...

  9. Hdu Binary Tree Traversals

    Problem Description         A binary tree is a finite set of vertices that is either empty or consis ...

  10. CSS蒙版

    蒙版:就是在图片上添加一个图层,用于美化页面,增加页面的可读性 <!DOCTYPE html><html><head lang="en"> &l ...