把括号序列后一定是))))((((这种形式的..所以维护一个最大前缀和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. 利用OpenCV和MFC对话框建设一个有滑动条控制的播放器--转

    (一)问题的提出: OpenCV有一个很简单的播放视频文件并加载滑动条的程序,但是如何用MFC对话框来创建一个有滑动条控制的播放器呢,网络上四处搜索都没有代码可以参考,下的都是些骗子链接文件,很过分, ...

  2. 《windows程序设计》学习_4:文本输出,加滚动条

    //总行数 #define NUMLINES ((int) (sizeof sysmetrics / sizeof sysmetrics [0])) struct { int Index ; TCHA ...

  3. centos6.5vpn搭建

    centos6.5vpn搭建整个搭建流程,服务端,客户端安装及测试. 达到的效果: 在安装vpn客户端的机器可通过vpn(virtual private network)专用线路(vpn主配置文件中定 ...

  4. #include <array>

    array是静态数组,在栈上,不可以变长 vector比array更常用 不需要变长,容量较小,用array 需要变长,容量较大,用vector 1 array 1 array新数组 //std::a ...

  5. I Hate It(线段树)

    I Hate It Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total S ...

  6. Android4.0设置界面改动总结(三)

    Android4.0设置界面改动总结大概介绍了一下设置改tab风格,事实上原理非常easy,理解两个基本的函数就可以: ①.invalidateHeaders(),调用此函数将又一次调用onBuild ...

  7. Unity5UGUI 官方教程学习笔记(四)UI Image

    Image Source image:源图片  需要显示的图片 Color:颜色  会与图片进行颜色的混合 Material:材质 Image Type:  Simple   精灵只会延伸到适合Rec ...

  8. JavaSE复习日记 : 多态

    /** * 里氏替换原则 : * 能使用父类的地方,一定可以使用子类 * 什么是多态 : * 父类的引用,指向子类的对象 * 多态的前提条件 : * 有继承关系的两个类 * 多态的目的 : * ☆☆☆ ...

  9. MFC的资源切换AFX_MANAGE_STATE(AfxGetStaticModuleState()

    转载自:http://blog.chinaunix.net/uid-20532101-id-1931929.html 以前写MFC的DLL的时候,总会在自动生成的代码框架里看到提示,需要在每一个输出的 ...

  10. Hibernate学习之常用方法比较

    一.save()和persist()方法 使用 save() 方法保存持久化对象时,该方法返回该持久化对象的标识属性值(即对应记录的主键值):但使用 persist() 方法来保存持久化对象时,该方法 ...