2329: [HNOI2011]括号修复
一开始以为可以直接线段树的,好像还是不行……还是得用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]括号修复的更多相关文章
- BZOJ 2329: [HNOI2011]括号修复( splay )
把括号序列后一定是))))((((这种形式的..所以维护一个最大前缀和l, 最大后缀和r就可以了..答案就是(l+1)/2+(r+1)/2...用splay维护,O(NlogN). 其实还是挺好写的, ...
- ●BZOJ 2329 [HNOI2011]括号修复.cpp
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=2329 题解: Splay 类似 BZOJ 2329 [HNOI2011]括号修复 只是多了一 ...
- 【BZOJ】2329: [HNOI2011]括号修复(splay+特殊的技巧)
http://www.lydsy.com/JudgeOnline/problem.php?id=2329 和前一题一样,不就多了个replace操作吗.好,就打一下. 然后交上去wa了........ ...
- BZOJ 2329: [HNOI2011]括号修复 [splay 括号]
题目描述 一个合法的括号序列是这样定义的: 空串是合法的. 如果字符串 S 是合法的,则(S)也是合法的. 如果字符串 A 和 B 是合法的,则 AB 也是合法的. 现在给你一个长度为 N 的由‘(' ...
- 2329: [HNOI2011]括号修复 - BZOJ
恶心的splay,打标记的时候还有冲突,要特别小心 上次写完了,查了半天没查出错来,于是放弃 今天对着标程打代码,终于抄完了,我已经不想再写了 const maxn=; type node=recor ...
- bzoj千题计划222:bzoj2329: [HNOI2011]括号修复(fhq treap)
http://www.lydsy.com/JudgeOnline/problem.php?id=2329 需要改变的括号序列一定长这样 :)))((( 最少改变次数= 多余的‘)’/2 [上取整] + ...
- 【BZOJ2329/2209】[HNOI2011]括号修复/[Jsoi2011]括号序列 Splay
[BZOJ2329/2209][HNOI2011]括号修复/[Jsoi2011]括号序列 题解:我们的Splay每个节点维护如下东西:左边有多少多余的右括号,右边有多少多余的左括号,同时为了反转操作, ...
- BZOJ 2329/2209 [HNOI2011]括号修复 (splay)
题目大意: 让你维护一个括号序列,支持 1.区间修改为同一种括号 2.区间内所有括号都反转 3.翻转整个区间,括号的方向不变 4.查询把某段区间变为合法的括号序列,至少需要修改多少次括号 给跪了,足足 ...
- BZOJ2329 [HNOI2011]括号修复
把左括号看做$1$,右括号看做$-1$,于是查询操作等于查询一个区间左边右边最大(最小)子段和 支持区间翻转,反转,覆盖操作...注意如果有覆盖操作,之前的操作全部作废了...于是在下传标记的时候要最 ...
随机推荐
- JMeter脚本获取变量名、检验字符串值
说明: 脚本中获取变量值用vars.get("变量名"); 校验String类型的值使用String.equals("字符串值"),而不能用String==&q ...
- three.js实现3D模型展示
由于项目需要展示3d模型,所以对three做了点研究,分享出来 希望能帮到大家 先看看效果: three.js整体来说 不是很难 只要你静下心来研究研究 很快就会上手的 首先我们在页面上需要创建一个能 ...
- [置顶]
Xamarin android 调用Web Api(ListView使用远程数据)
xamarin android如何调用sqlserver 数据库呢(或者其他的),很多新手都会有这个疑问.xamarin android调用远程数据主要有两种方式: 在Android中保存数据或调用数 ...
- 对于group by 和 order by 并用 的分析
今天朋友问我一个sql查询. 需求是 找到idapi最近那条数据,说明idapi 是重复的,于是就简单的写了 SELECT * FROM `ag_alarm_history` group by ` ...
- git pull与git fetch的区别
git pull: 取回远程主机某个分支的更新,再与本地的指定分支合并. 用法: git pull <远程仓库> <远程分支名>:<本地分支名> // 如 git ...
- 实体框架(Entity Frmaework)简介
l简称EF NH l与Asp.Net MVC关系与ADO.NET关系 lADO.NET Entity Framework 是微软以 ADO.NET 为基础所发展出来的对象关系对应 (O/R Mapp ...
- 解决Windows和Linux使用npm打包js和css文件不同的问题
1.问题出现 最近公司上线前端H5页面,使用npm打包,特别奇怪的是每次打包发现css和js文件与Windows下打包不一致(网页使用Windows环境开发),导致前端页面功能不正常. 2.问题排查 ...
- Vue 爬坑之路(九)—— 用正确的姿势封装组件
迄今为止做的最大的 Vue 项目终于提交测试,天天加班的日子终于告一段落... 在开发过程中,结合 Vue 组件化的特性,开发通用组件是很基础且重要的工作 通用组件必须具备高性能.低耦合的特性 为了满 ...
- 【精选】Nginx模块Lua-Nginx-Module学习笔记(二)Lua指令详解(Directives)
源码地址:https://github.com/Tinywan/Lua-Nginx-Redis Nginx与Lua编写脚本的基本构建块是指令. 指令用于指定何时运行用户Lua代码以及如何使用结果. 下 ...
- linux网路编程:字节序(大端、小端、网络、主机)
字节序:就是数据在内存中的存放顺序,也可称之为端模式. 大端模式和小端模式的定义 1) Little-Endian就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端. 2) Big-End ...