把括号序列后一定是))))((((这种形式的..所以维护一个最大前缀和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. VC2008如何生成及使用DLL(完整版)

    生成.使用DLL看起来简单,但做起来才发现还是有一些地方需要注意的. 1. 打开VS2008,新建一个VC工程,选择Win32类型,Win32项目: 2. 应用程序类型选择DLL,附加选项选择到处符号 ...

  2. 【转】stdin, stdout, stderr 以及重定向

    详细见: http://my.oschina.net/qihh/blog/55308 stdin是标准输入文件,stdout是标准输出文件,stderr标准出错文件. 程序按如下方式使用这些文件: 标 ...

  3. 采用proguard困惑android代码

    当前是有些工具比方apktool,dextojar等是能够对我们android安装包进行反编译.获得源代码的.为了降低被别人破解,导致源代码泄露,程序被别人盗代替码,等等.我们须要对代码进行混淆.an ...

  4. sass安装步骤

    sass 基于Ruby,首先需要安装Ruby.当然也有node-sass,那是另外一种使用方式了.如果能FQ的,就不用看了,主要写给翻不了墙的人用. 1.安装Ruby,ruby下载地址: http:/ ...

  5. jquery常用语句总结

    一.jquery中text val html attr的使用区别 html和innerHTMl是一样的,可以获得和设置指定元素如<p>中的html标签和文本如:设置值: $("p ...

  6. 【图像配准】基于灰度的模板匹配算法(一):MAD、SAD、SSD、MSD、NCC、SSDA、SATD算法

    简介: 本文主要介绍几种基于灰度的图像匹配算法:平均绝对差算法(MAD).绝对误差和算法(SAD).误差平方和算法(SSD).平均误差平方和算法(MSD).归一化积相关算法(NCC).序贯相似性检测算 ...

  7. NOPI导出Excel

    NOPI导出Excel /// <summary> /// 导出的方法 Excel样式 /// </summary> /// <param name="ds&q ...

  8. 菜鸟初试水--JQuery基础

    此文仅作入门级文章,望大神们高抬贵手! JQuery: 它是一套跨浏览器的JavaScript库,简化HTML与JavaScript之间的操作. JQuery的用途: ①访问和操作DOM元素: 使用j ...

  9. calltree看代码调用图

    calltree是在linux下面看c代码(尤其是复杂的内核代码)的神器. 推荐  calltree+vim + ctags + cscope + taglist [ vim: 搭建vim看代码的环境 ...

  10. IT工程师值得一看的书籍

    http://blog.csdn.net/chinahuyong/article/details/45060203