BZOJ2329: [HNOI2011]括号修复(Splay)
解题思路:
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)的更多相关文章
- BZOJ2329 HNOI2011 括号修复 splay+贪心
找平衡树练习题的时候发现了这道神题,可以说这道题是近几年单考splay的巅峰之作了. 题目大意:给出括号序列,实现区间翻转,区间反转和区间更改.查询区间最少要用几次才能改成合法序列. 分析: 首先我们 ...
- BZOJ 2329: [HNOI2011]括号修复( splay )
把括号序列后一定是))))((((这种形式的..所以维护一个最大前缀和l, 最大后缀和r就可以了..答案就是(l+1)/2+(r+1)/2...用splay维护,O(NlogN). 其实还是挺好写的, ...
- bzoj千题计划222:bzoj2329: [HNOI2011]括号修复(fhq treap)
http://www.lydsy.com/JudgeOnline/problem.php?id=2329 需要改变的括号序列一定长这样 :)))((( 最少改变次数= 多余的‘)’/2 [上取整] + ...
- 【bzoj2329】[HNOI2011]括号修复 Splay
题目描述 题解 Splay 由于有区间反转操作,因此考虑Splay. 考虑答案:缩完括号序列后剩下的一定是 $a$ 个')'+ $b$ 个'(',容易发现答案等于 $\lceil\frac a2\rc ...
- BZOJ 2329: [HNOI2011]括号修复 [splay 括号]
题目描述 一个合法的括号序列是这样定义的: 空串是合法的. 如果字符串 S 是合法的,则(S)也是合法的. 如果字符串 A 和 B 是合法的,则 AB 也是合法的. 现在给你一个长度为 N 的由‘(' ...
- BZOJ 2329/2209 [HNOI2011]括号修复 (splay)
题目大意: 让你维护一个括号序列,支持 1.区间修改为同一种括号 2.区间内所有括号都反转 3.翻转整个区间,括号的方向不变 4.查询把某段区间变为合法的括号序列,至少需要修改多少次括号 给跪了,足足 ...
- BZOJ2329 [HNOI2011]括号修复
把左括号看做$1$,右括号看做$-1$,于是查询操作等于查询一个区间左边右边最大(最小)子段和 支持区间翻转,反转,覆盖操作...注意如果有覆盖操作,之前的操作全部作废了...于是在下传标记的时候要最 ...
- 2019.03.25 bzoj2329: [HNOI2011]括号修复(fhq_treap)
传送门 题意简述: 给一个括号序列,要求支持: 区间覆盖 区间取负 区间翻转 查询把一个区间改成合法括号序列最少改几位 思路: 先考虑静态的时候如何维护答案. 显然把所有合法的都删掉之后序列长这样: ...
- 【BZOJ2329/2209】[HNOI2011]括号修复/[Jsoi2011]括号序列 Splay
[BZOJ2329/2209][HNOI2011]括号修复/[Jsoi2011]括号序列 题解:我们的Splay每个节点维护如下东西:左边有多少多余的右括号,右边有多少多余的左括号,同时为了反转操作, ...
随机推荐
- Kinect for Windows V2 SDK+ VS2012 环境搭建
眼下使用的SDK版本号是KinectSDK-v2.0-PublicPreview1409-Setup.exe. 下载地址:http://www.microsoft.com/en-us/download ...
- CSS元素选择器 element selector(type selector)
http://www.w3school.com.cn/css/css_selector_type.asp 元素选择器 最常见的 CSS 选择器是元素选择器.换句话说,文档的元素就是最基本的选择器. 如 ...
- Android活动状态和生存期
活动状态 1.运行状态(顶层的活动) 2.暂停状态(非顶层的,可见的活动) 3.停止状态(非顶层的,不可见的活动) 4.销毁状态(保证手机的内存充足) 活动的生存期 完整的生存期 onCreate活动 ...
- php中对象转数组有哪些方法(总结测试)
php中对象转数组有哪些方法(总结测试) 一.总结 一句话总结:json_decode(json_encode($array),true)和array强制转换(或带递归) 1.array方式强制转换对 ...
- poj--2007--Scrambled Polygon(数学几何基础)
Scrambled Polygon Time Limit: 1000MS Memory Limit: 30000KB 64bit IO Format: %I64d & %I64u Su ...
- Linux 内核源码(kernel source)
查看内核的发行版:uname -r(--kernel-release) $ uname -r 4.4.0-78-generic 内核源码所在的位置:/usr/src $ cd /usr/src $ l ...
- Android真机调试访问本地服务器(localhost)的解决方案
Android系统把它自己作为了localhost!当连接localhost都是他自己啊.. 囧,在这里晕了好久才发现.. 网上介绍的都是模拟器连接本地服务器的,我试着把链接改为http://10.0 ...
- 洛谷——P1155 双栈排序
题目描述 Tom最近在研究一个有趣的排序问题.如图所示,通过2个栈S1和S2,Tom希望借助以下4种操作实现将输入序列升序排序. 操作a 如果输入序列不为空,将第一个元素压入栈S1 操作b 如果栈S1 ...
- Ubuntu中的解压缩文件的方式
记录Ubuntu下各种压缩和解压方式: .tar 解包:tar xvf FileName.tar 打包:tar cvf FileName.tar DirName (注:tar是打包,不是压缩!) -- ...
- Codeforces 164 D Minimum Diameter
题目链接~~> 做题感悟:越来越感觉CF的题非常好,非常有深度. 解题思路: 这题须要注意 k 的大小.由于 k 仅仅有 30 个,终于形成的点的直径一定是某个确定的值,所以我们能够枚举这个值. ...
