传送魔法

  一开始以为可以直接线段树的,好像还是不行……还是得用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. spring cloud sidecar

    用spring cloud sidecar的整合异构语言,以前做过没有做笔记,现在再做由于各种坑又浪费了一天,这里记一下 首先是官网:http://cloud.spring.io/spring-clo ...

  2. 链接文本在a标签内标签里也可以用driver.find_element_by_link_text

    如: 也可用driver.find_element_by_link_text("账户登录").click()

  3. Hibernate学习---Configuration,Session,SessionFactory

    上一节我们讲到了Hibernate的测试,并且给出了测试代码,刚开始看见这个测试代码的同学估计是一头雾水把,所以这一节我们来讲一下测试代码. 本节主要内容: Configuration Session ...

  4. ES6字符串方法

    ES6字符串提供三个函数确定一个字符串是否包含在另一个字符串中,分别是includes().startsWith().endsWith(),这三种方法都返回一个布尔值. includes()方法表示是 ...

  5. 来腾讯云开发者实验室 学习.NET

    腾讯云开发者实验室为开发者提供了一个零门槛的在线实验平台,开发者实验室提供的能力: 零门槛扫码即可免费领取实验机器,支持使用自有机器参与,实验完成后支持保留实验成果: 在线 WEB IDE 支持 sh ...

  6. php编码的一些小规范

    本文同时发表在https://github.com/zhangyachen/zhangyachen.github.io/issues/104 最近在整理线上的hhvm warning,虽然每天产生百万 ...

  7. MAMP升级mysql5.6到5.7

    RT 1.先把mamp环境停掉 sudo sh /Applications/MAMP/bin/stop.sh 2.然后使用brew安装mysql5.7 brew install mysql 3.默认安 ...

  8. Docker(七):Docker容器卷管理

    1.使用容器卷的原因:Docker容器产生的数据,如果不通过commit生成新的镜像,数据会在容器删除后丢失.为了能持久化保存和共享容器的数据,Docker提出了两种管理数据的方式:数据卷和数据卷容器 ...

  9. Golang 网络爬虫框架gocolly/colly 三

    Golang 网络爬虫框架gocolly/colly 三 熟悉了<Golang 网络爬虫框架gocolly/colly一>和<Golang 网络爬虫框架gocolly/colly二& ...

  10. Django2.0中文文档

    title: Django2.0中文文档 tags: Python,Django,入沐三分 grammar_cjkRuby: true --- Django2.0版本已经发布了,我们先来看一个图片 从 ...