解题思路:

Replace、Swap、Invert都可以使用Splay完美解决(只需要解决一下标记冲突就好了)。

最后只需要统计左右括号冲突就好了。

相当于动态统计最大前缀合和最小后缀和。

因为支持翻转反转操作,翻转标记或取反就好了。

代码:

 #include<cstdio>
#include<cstring>
#include<algorithm>
#define lll tr[spc].ch[0]
#define rrr tr[spc].ch[1]
#define ls ch[0]
#define rs ch[1]
typedef long long lnt;
const int N=;
struct trnt{
int ch[];
int fa;
int wgt;
int val;
int sum;
int mxp;
int mnp;
int mxs;
int mns;
int lzt;
bool rev;
bool ant;
}tr[N];
int n,m;
int siz;
int root;
int num[N];
char cmd[N];
bool whc(int spc)
{
return tr[tr[spc].fa].rs==spc;
}
void pushup(int spc)
{
tr[spc].wgt=;
if(lll)
tr[spc].wgt+=tr[lll].wgt;
if(rrr)
tr[spc].wgt+=tr[rrr].wgt;
tr[spc].sum=tr[spc].val;
if(lll)
tr[spc].sum+=tr[lll].sum;
if(rrr)
tr[spc].sum+=tr[rrr].sum;
tr[spc].mxp=tr[spc].mxs=std::max(tr[spc].sum,);
tr[spc].mnp=tr[spc].mns=std::min(,tr[spc].sum);
if(lll)
{
tr[spc].mxp=std::max(tr[spc].mxp,std::max(tr[lll].mxp,tr[lll].sum+tr[spc].val));
tr[spc].mnp=std::min(tr[spc].mnp,std::min(tr[lll].mnp,tr[lll].sum+tr[spc].val));
tr[spc].mxs=std::max(tr[spc].mxs,std::max(tr[rrr].sum+tr[spc].val,tr[spc].val+tr[lll].mxs+tr[rrr].sum));
tr[spc].mns=std::min(tr[spc].mns,std::min(tr[rrr].sum+tr[spc].val,tr[spc].val+tr[lll].mns+tr[rrr].sum));
}
if(rrr)
{
tr[spc].mxs=std::max(tr[spc].mxs,std::max(tr[rrr].mxs,tr[rrr].sum+tr[spc].val));
tr[spc].mns=std::min(tr[spc].mns,std::min(tr[rrr].mns,tr[rrr].sum+tr[spc].val));
tr[spc].mxp=std::max(tr[spc].mxp,std::max(tr[lll].sum+tr[spc].val,tr[spc].val+tr[lll].sum+tr[rrr].mxp));
tr[spc].mnp=std::min(tr[spc].mnp,std::min(tr[lll].sum+tr[spc].val,tr[spc].val+tr[lll].sum+tr[rrr].mnp));
}
return ;
}
void trr(int spc)
{
if(!spc)
return ;
std::swap(lll,rrr);
std::swap(tr[spc].mxp,tr[spc].mxs);
std::swap(tr[spc].mnp,tr[spc].mns);
tr[spc].rev^=;
return ;
}
void anti(int spc)
{
if(!spc)
return ;
tr[spc].val*=-;
tr[spc].sum*=-;
tr[spc].mxp*=-;
tr[spc].mnp*=-;
tr[spc].mxs*=-;
tr[spc].mns*=-;
std::swap(tr[spc].mxp,tr[spc].mnp);
std::swap(tr[spc].mxs,tr[spc].mns);
tr[spc].ant^=;
return ;
}
void chg(int spc,int v)
{
if(!spc)
return ;
tr[spc].ant=false;
tr[spc].val=v;
tr[spc].lzt=v;
tr[spc].sum=v*tr[spc].wgt;
if(v==)
{
tr[spc].mnp=;
tr[spc].mns=;
tr[spc].mxp=v*tr[spc].wgt;
tr[spc].mxs=v*tr[spc].wgt;
}else{
tr[spc].mxp=;
tr[spc].mxs=;
tr[spc].mnp=v*tr[spc].wgt;
tr[spc].mns=v*tr[spc].wgt;
}
return ;
}
void pushdown(int spc)
{
if(tr[spc].rev)
{
trr(lll);
trr(rrr);
tr[spc].rev=false;
}
if(tr[spc].lzt)
{
chg(lll,tr[spc].lzt);
chg(rrr,tr[spc].lzt);
tr[spc].lzt=;
}
if(tr[spc].ant)
{
anti(lll);
anti(rrr);
tr[spc].ant=false;
}
return ;
}
void recal(int spc)
{
if(tr[spc].fa)
recal(tr[spc].fa);
pushdown(spc);
return ;
}
void rotate(int spc)
{
int f=tr[spc].fa;
bool k=whc(spc);
tr[f].ch[k]=tr[spc].ch[!k];
tr[spc].ch[!k]=f;
tr[tr[f].fa].ch[whc(f)]=spc;
tr[spc].fa=tr[f].fa;
tr[f].fa=spc;
tr[tr[f].ch[k]].fa=f;
pushup(f);
pushup(spc);
return ;
}
void splay(int spc,int f)
{
recal(spc);
while(tr[spc].fa!=f)
{
int ft=tr[spc].fa;
if(tr[ft].fa==f)
{
rotate(spc);
break;
}
if(whc(spc)^whc(ft))
rotate(spc);
else
rotate(ft);
rotate(spc);
}
if(!f)
root=spc;
return ;
}
void Build(int l,int r,int &spc,int f)
{
if(l>r)
return ;
int mid=(l+r)>>;
spc=++siz;
tr[spc].val=num[mid];
tr[spc].fa=f;
Build(l,mid-,lll,spc);
Build(mid+,r,rrr,spc);
pushup(spc);
return ;
}
int plc(int spc,int k)
{
pushdown(spc);
if(tr[lll].wgt>=k)
return plc(lll,k);
if(tr[lll].wgt+==k)
return spc;
return plc(rrr,k-tr[lll].wgt-);
}
void rush(int l,int r)
{
l=plc(root,l);
r=plc(root,r+);
splay(l,);
splay(r,root);
return ;
}
int main()
{
scanf("%d%d",&n,&m);
scanf("%s",cmd+);
for(int i=;i<=n;i++)
num[i]=((cmd[i]==')')<<)-;
Build(,n+,root,);
while(m--)
{
int l,r;
scanf("%s",cmd+);
scanf("%d%d",&l,&r);
rush(l,r);
if(cmd[]=='R')
{
scanf("%s",cmd+);
chg(tr[tr[root].rs].ls,((cmd[]==')')<<)-);
}else if(cmd[]=='S')
trr(tr[tr[root].rs].ls);
else if(cmd[]=='I')
anti(tr[tr[root].rs].ls);
else{
int spc=tr[tr[root].rs].ls;
printf("%d\n",(tr[spc].mxp+)/+(-tr[spc].mns+)/);
}
pushup(tr[root].rs);
pushup(root);
}
return ;
}

BZOJ2329: [HNOI2011]括号修复(Splay)的更多相关文章

  1. BZOJ2329 HNOI2011 括号修复 splay+贪心

    找平衡树练习题的时候发现了这道神题,可以说这道题是近几年单考splay的巅峰之作了. 题目大意:给出括号序列,实现区间翻转,区间反转和区间更改.查询区间最少要用几次才能改成合法序列. 分析: 首先我们 ...

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

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

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

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

  4. 【bzoj2329】[HNOI2011]括号修复 Splay

    题目描述 题解 Splay 由于有区间反转操作,因此考虑Splay. 考虑答案:缩完括号序列后剩下的一定是 $a$ 个')'+ $b$ 个'(',容易发现答案等于 $\lceil\frac a2\rc ...

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

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

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

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

  7. BZOJ2329 [HNOI2011]括号修复

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

  8. 2019.03.25 bzoj2329: [HNOI2011]括号修复(fhq_treap)

    传送门 题意简述: 给一个括号序列,要求支持: 区间覆盖 区间取负 区间翻转 查询把一个区间改成合法括号序列最少改几位 思路: 先考虑静态的时候如何维护答案. 显然把所有合法的都删掉之后序列长这样: ...

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

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

随机推荐

  1. Android调试命令总结

    转载表明来源:http://blog.csdn.net/yzzst/article/details/47128581 创业要接地气,GOOGLE.亚马逊.微软在中国做的怎么样,全然取决于他们的本地化程 ...

  2. Android开发之蓝牙(Bluetooth)操作(二)--修改本机蓝牙设备的可见性,并扫描周围可用的蓝牙设备

    版权声明:本文为博主原创文章,未经博主允许不得转载. 一. 修改本机蓝牙设备的可见性 二. 扫描周围可用的蓝牙设备 Eg: 一.  清单文件AdroidManifest.xml: <?xml v ...

  3. Bootstrap概览

    摘选自runnoob.com,bootstrap4所有api概览: 一.安装: 弹性盒子(flexbox) Bootstrap 3 与 Bootstrap 4 最大的区别就是 Bootstrap 4 ...

  4. WebAssembly学习(五):AssemblyScript - Hello World

    一.项目创建 1.创建AssemblyScript根目录 mkdir AssemblyScript 2.安装AssemblyScript开发依赖 cnpm install --save-dev Ass ...

  5. Mark Compact GC (Part two :Two-Finger)

    目录 Two-Finger算法 前提 概要 步骤一:移动对象 步骤二:更新指针 优缺点 表格算法 概要 步骤一:移动对象群 和 构筑间隙表格 移动对象群 构筑间隙表格 步骤二:更新指针 优缺点 Two ...

  6. 云计算时代告别phpMyAdmin

    云计算时代告别phpMyAdmin phpMyAdmin是一款很经典的MySQL数据库管理工具,在云计算快速发展的今天,phpMyAdmin交互老旧.已经不能适应时代步伐.因此有很多人開始选择一些更高 ...

  7. 单线程实现检索当当网泄露的1GB用户数据

     新建项目dangdangusersearch 2.编写头文件head.h #ifndef _HEAD_H_ #define _HEAD_H_ #include <stdio.h>   ...

  8. Resize图片

    在网站上传图片的时候,提示图片太大了. 有5种方式来调整图片大小 http://www.wikihow.com/Resize-a-JPEG picresize.com 这个网站比较靠谱:使用Windo ...

  9. .Net 自动属性结合手动属性

    Model using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace ...

  10. call 方法和 apply方法

    1.方法定义 call方法: 语法:call([thisObj[,arg1[, arg2[,   [,.argN]]]]]) 定义:调用一个对象的一个方法,以另一个对象替换当前对象. 说明: call ...