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$,于是查询操作等于查询一个区间左边右边最大(最小)子段和 支持区间翻转,反转,覆盖操作...注意如果有覆盖操作,之前的操作全部作废了...于是在下传标记的时候要最 ...
随机推荐
- HTML状态码大全(301,404,500等)
HTML状态码大全(301,404,500等)HTML状态码大全(301,404,500等)HTML状态码大全(301,404,500等)HTML状态码大全(301,404,500等) 这些状态码被分 ...
- Data Base mongodb driver2.5环境注意事项
mongodb driver2.5环境注意事项 一.问题: 如果使用vs2012开发就会报这个错误: 未能加载文件或程序集“System.Runtime.InteropServices.Runtime ...
- JAVA 实现tail -f 日志文件监控功能
工具: <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</ar ...
- whereis 命令详解
whereis 作用:whereis命令只能用于程序名的搜索,而且只搜索二进制文件(参数-b).man说明文件(参数-m)和源代码文件(参数-s).如果省略参数,则返回所有信息. 参数:-b 定位可 ...
- ogg12c_静默安装
1.上传压缩包:123010_fbo_ggs_Linux_x64_shiphome.zip 2.解压: unzip 123010_fbo_ggs_Linux_x64_shiphome.zip 3.配置 ...
- Webpack 2 视频教程 019 - Webpack 2 中配置多页面编译
原文发表于我的技术博客 这是我免费发布的高质量超清「Webpack 2 视频教程」. Webpack 作为目前前端开发必备的框架,Webpack 发布了 2.0 版本,此视频就是基于 2.0 的版本讲 ...
- pyshark 得到payload
mydata = pkt[okt.highest_layer].data mydata.decode("hex")
- HBase跨地区机房的压测小程序——从开发到打包部署(图文版)
今天做了一个跨地区机房的压测小程序,主要的思路就是基于事先准备好的rowkey文件,利用多线程模拟并发的rowkey查询,可以实现并发数的自由控制.主要是整个流程下来,遇到了点打包的坑,所以特意记录下 ...
- JQ trigger函数无法触发a标签的两种解决方法
起因:点击icon图标后要触发a标签的链接转跳动作,但是用 JQ 的 $('#a').trigger('click') 居然不起作用,遂百度之,总结两种方法如下: (原因:JQ 的 trigger() ...
- 用元类和__getattribute__改变类属性的读取方式
首先,需要知道两点: 类本身是type类的实例 __getattribute__ 可以改变类实例的属性的读取方式(http://www.cnblogs.com/blackmatrix/p/568148 ...