把括号序列后一定是))))((((这种形式的..所以维护一个最大前缀和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. 接口返回json

    use Mojolicious::Lite; use JSON qw/encode_json decode_json/; # /foo?user=sri get '/api' => sub { ...

  2. MFC渐入渐出框实现方式二

    类似360消息弹出框,实现方式一见http://blog.csdn.net/segen_jaa/article/details/7848598. 本文采用另外的API实现渐入渐出效果. 主要API:S ...

  3. poj2405---体积几何

    #include <stdio.h> #include <stdlib.h> #include<math.h> #define pi acos(-1) int ma ...

  4. Hibernate 数据的批量插入、更新和删除

    4.2  Hibernate的批量处理 Hibernate完全以面向对象的方式来操作数据库,当程序里以面向对象的方式操作持久化对象时,将被自动转换为对数据库的操作.例如调用Session的delete ...

  5. appium locator

    If you want to find out more about the UIAutomator library, then it might be helpful to check out ht ...

  6. 【asp.net】将GridView数据导出Excel

    概要: 中午睡了一会,醒来的时候看到老师叫我去办公室,需求是这样的,把excel表中的每个同学,判断图片目录中是否有对应的照片(图片的名字用的学号或身份证号码) 没有对应图片的学生记录,存入自己的数据 ...

  7. excel导出、导入功能

    public class ExcelHelper { #region 数据导出至Excel文件 /// </summary> /// web导出Excel文件,自动返回可下载的文件流 // ...

  8. qt检测网络连接状态【只能检测和路由器的连接,不能测试到外网的连接】

    #include <QCoreApplication>#include <QDebug>#include <QTextStream>#include <QDi ...

  9. B - Moving Tables

    B - Moving Tables Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u S ...

  10. 理解ROS的参数

    记住每次操作之前都要在一个单独的终端中运行ros的核心. roscore rosparam命令允许你在ROS的参数服务器上操作和存储数据,参数服务器可以存储整数,浮点数,布尔类型,字典,列表.ROS使 ...