传送魔法

  一开始以为可以直接线段树的,好像还是不行……还是得用Spaly,然后就没啥了。

#include<cstdio>
#include<algorithm>
#define MN 210000
using namespace std; inline int read(){
int ca=getchar(),p=;
while (ca<''||ca>'') ca=getchar();
while (ca>=''&&ca<='') p=p*+ca-,ca=getchar();
return p;
}
struct na{int s,qm,qi,hm,hi;na(int _s=,int _qm=,int _qi=,int _hm=,int _hi=):s(_s),qm(_qm),qi(_qi),hm(_hm),hi(_hi){};};
struct tree{
int f,c[],k,s,S;
na w;
bool rev,cg;
}t[MN];
char s[MN];
int n,m,num=,st[MN],top,root,l,r;
na hb(na a,na b){
na c;
c.s=a.s+b.s;
c.qm=max(a.qm,b.qm+a.s);
c.qi=min(a.qi,b.qi+a.s);
c.hm=max(b.hm,a.hm+b.s);
c.hi=min(b.hi,a.hi+b.s);
return c;
}
inline void REV(int p){
if (!p) return;
t[p].w=na(t[p].w.s,t[p].w.hm,t[p].w.hi,t[p].w.qm,t[p].w.qi);
swap(t[p].c[],t[p].c[]);
t[p].rev^=;
}
inline void REP(int p,int s){
if (!p) return;t[p].k=s;t[p].rev=t[p].cg=;
if (s==) t[p].w=na(t[p].S,t[p].S,,t[p].S,);else t[p].w=na(-t[p].S,,-t[p].S,,-t[p].S);
t[p].s=s;
}
inline void CG(int p){
if (!p) return;
t[p].cg^=;t[p].k*=-;
t[p].w=na(-t[p].w.s,-t[p].w.qi,-t[p].w.qm,-t[p].w.hi,-t[p].w.hm);
}
inline void gx(int p){
if (t[p].k==) t[p].w=na(,,,,);else t[p].w=na(-,,-,,-);
if (t[p].c[])t[p].w=hb(t[t[p].c[]].w,t[p].w);
if (t[p].c[])t[p].w=hb(t[p].w,t[t[p].c[]].w);
t[p].S=t[t[p].c[]].S+t[t[p].c[]].S+;
}
inline void pd(int p){
if (t[p].s) REP(t[p].c[],t[p].s),REP(t[p].c[],t[p].s),t[p].s=;
if (t[p].rev) REV(t[p].c[]),REV(t[p].c[]),t[p].rev=;
if (t[p].cg) CG(t[p].c[]),CG(t[p].c[]),t[p].cg=;
}
void build(int &p,int l,int r){
if (l>r) return;
int mid=l+r>>;
p=mid+;t[p].s=t[p].rev=;
if (s[mid]=='(') t[p].k=;else t[p].k=-;
build(t[p].c[],l,mid-);build(t[p].c[],mid+,r);
t[t[p].c[]].f=t[t[p].c[]].f=p;
gx(p);
}
void rot(int &p,bool bo){
int k=t[p].c[bo];
t[p].c[bo]=t[k].c[!bo];
t[k].c[!bo]=p;
t[t[p].c[bo]].f=p;
t[k].f=t[p].f;
t[p].f=k;
gx(p);gx(k);
p=k;
}
inline bool gc(int p){return t[t[p].f].c[]==p;}
inline void ph(int p){if (t[p].f==root) rot(root,gc(p));else rot(t[t[t[p].f].f].c[gc(t[p].f)],gc(p));}
void spaly(int p,int f){
top=;
for (int i=p;i;i=t[i].f) st[++top]=i;
while (top) pd(st[top--]);
while (t[p].f!=f)
if (t[t[p].f].f==f) ph(p);else
if (gc(p)==gc(t[p].f)) ph(t[p].f),ph(p);else ph(p),ph(p);
}
int fi(int p,int k){
pd(p);
if (t[t[p].c[]].S>=k) return fi(t[p].c[],k);else
if (t[t[p].c[]].S+==k) return p;else return fi(t[p].c[],k--t[t[p].c[]].S);
}
inline void rep(){
int l,r;
l=fi(root,read());r=fi(root,read()+);scanf("%s",s);
spaly(l,);spaly(r,l);
REP(t[r].c[],s[]=='('?:-);
}
inline void sw(){
int l,r;
l=fi(root,read());r=fi(root,read()+);
spaly(l,);spaly(r,l);
REV(t[r].c[]);
}
inline void cg(){
int l,r;
l=fi(root,read());r=fi(root,read()+);
spaly(l,);spaly(r,l);
CG(t[r].c[]);
}
inline void que(){
int l,r;
l=fi(root,read());r=fi(root,read()+);
spaly(l,);spaly(r,l);
printf("%d\n",(t[t[r].c[]].w.hm+>>)+(-t[t[r].c[]].w.qi+>>));
}
int main(){
n=read();m=read();
scanf("%s",s+);
build(root,,n+);
while (m--){
scanf("%s",s);
if (s[]=='R') rep();else
if (s[]=='S') sw();else
if (s[]=='I') cg();else que();
}
}

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

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

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

  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: [HNOI2011]括号修复 [splay 括号]

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

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

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

  6. bzoj千题计划222:bzoj2329: [HNOI2011]括号修复(fhq treap)

    http://www.lydsy.com/JudgeOnline/problem.php?id=2329 需要改变的括号序列一定长这样 :)))((( 最少改变次数= 多余的‘)’/2 [上取整] + ...

  7. 【BZOJ2329/2209】[HNOI2011]括号修复/[Jsoi2011]括号序列 Splay

    [BZOJ2329/2209][HNOI2011]括号修复/[Jsoi2011]括号序列 题解:我们的Splay每个节点维护如下东西:左边有多少多余的右括号,右边有多少多余的左括号,同时为了反转操作, ...

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

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

  9. BZOJ2329 [HNOI2011]括号修复

    把左括号看做$1$,右括号看做$-1$,于是查询操作等于查询一个区间左边右边最大(最小)子段和 支持区间翻转,反转,覆盖操作...注意如果有覆盖操作,之前的操作全部作废了...于是在下传标记的时候要最 ...

随机推荐

  1. iOS手机截屏使用

    .截屏 保存 .data //登录成功进行截屏 //截取屏幕大小 UIGraphicsBeginImageContext([[UIScreen mainScreen]bounds].size); [s ...

  2. Qt之移动硬盘热插拔监控

    最近在做一个通用对话框,类似于windows的资源管理器,当然了没有windwos资源管理器那么强大.用户报了一个bug,说通用对话框打开之后不能实时监控U盘插入,随手在百度上搜索了一圈,这个问题还是 ...

  3. Linux Centos7配置防火墙开启端口

    在使用centos7安装完mysql.tomcat.nginx后,都需要配置防火墙才能正常访问. 下面系统的学习一下防火墙的配置. centos7默认使用firewall,需要关闭,然后使用iptab ...

  4. SQL语句 我喜欢上海

    select * from [user] wherer name like '上海%'

  5. websocket(二) websocket的简单实现,识别用户属性的群聊

    没什么好说的,websocket实现非常简单,我们直接看代码. 运行环境:jdk8 tomcat8 无须其他jar包. 具体环境支持自己百度 package com.reach.socketContr ...

  6. MySQL5.6中date和string的转换和比较

    Conversion & Comparison, involving strings and dates in MySQL 5.6 我们有张表,表中有一个字段dpt_date,SQL类型为da ...

  7. C语言学生管理系统(增进版)

    在原版上进行改进,主要改进的功能有. 1.利用atof:将字符串转换为浮点型: 利用atoi:将字符串转换为整型: 原文地址:http://www.cnblogs.com/sddai/p/577412 ...

  8. 企业网盘: Owncloud 搭建

    说明:搭建很简单,就是一个lamp环境,但是最新的owncloud 9.x版本对php的版本需求不能低于5.4, 所以需要下载yum源来进行安装. 搭建过程 1)配置yum源 rpm -Uvh htt ...

  9. vexx 邀请码 送3个比特龙

    错过了比特币的行情,注册获取3个原始比特币分叉币,比特龙. 目前10元一个,送3个币.类似于股票IPO,第一天一般会冲高十几倍,建议第一天就卖. 如果看好就继续持有吧. 放心是送的不用钱的. 注册网址 ...

  10. 14.MySQL(二)

    数据之表操作 1.创建表 语法:CREATE TABLE table_name (column_name column_type); create table student( -> id IN ...