题链:

Splay
很好的题,但是把智障的我给恶心到了。。。
 
首先不难发现,最后没有匹配的括号的样子一定是 ))))..((((...
即左边是右括号(设个数为nr),右边是做括号(设个数为nl)
则答案为 ⌈nl÷2⌉ + ⌈nr÷2⌉ (⌈ ⌉:向上取整)
 
若把 '(' 看成 1,把 ')' 看成 -1,
那么在这个只含有 1 和 -1 的序列里,
前缀最小值的相反数就等于nr,
后缀最大值的就等于nl
 
所以对于询问操作来说,在Splay中记录:
key[x](节点x是 1 还是 -1)
sum[x](x子树对应区间的sum和)
pmn[x](x子树对应区间的前缀最小值),
smx[x](x子树对应区间的后缀最大值)。
 
对于第二个反转操作
可以看出,只是把对应区间的 1→ -1,-1→ 1,
所以再多维护两个东西
pmx[x](x子树对应区间的前缀最大值),
smn[x](x子树对应区间的后缀最小值)。
然后把记录的 key[x],sum[x],pmn[x],pmx[x],smn[x],smx[x]全部取反(都乘上-1),
并且 swap(pmn[x],pmx[x]), swap(smn[x],smx[x])(因为取反了啊~)
再打个lazy标记,就好啦。
 
对于第三个翻转操作
就只需交换左右子树,
并且 swap(pmx[x],smx[x]),swap(pmn[x],smn[x]) (只是把序列反了起来,所以交换前后缀信息即可)
然后打一个lazy标记。
 
因为lazy标记不存在先后影响,所以lazy下放时随便先放哪个都可以的。
 
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#define MAXN 100500
using namespace std;
int N,M;
struct SPT{
int pmx[MAXN],pmn[MAXN],smx[MAXN],smn[MAXN],sum[MAXN],key[MAXN];
int ch[MAXN][2],siz[MAXN],fa[MAXN],lazy[MAXN],rt;
void Reverse(int x){
sum[x]*=-1; key[x]*=-1;
pmx[x]*=-1; pmn[x]*=-1; swap(pmx[x],pmn[x]);
smx[x]*=-1; smn[x]*=-1; swap(smx[x],smn[x]);
}
void Flip(int x){
swap(pmx[x],smx[x]);
swap(pmn[x],smn[x]);
swap(ch[x][0],ch[x][1]);
}
void Pushup(int x){
siz[x]=siz[ch[x][0]]+1+siz[ch[x][1]];
sum[x]=sum[ch[x][0]]+key[x]+sum[ch[x][1]];
pmx[x]=max(pmx[ch[x][0]],sum[ch[x][0]]+key[x]+pmx[ch[x][1]]);
pmn[x]=min(pmn[ch[x][0]],sum[ch[x][0]]+key[x]+pmn[ch[x][1]]);
smx[x]=max(smx[ch[x][1]],sum[ch[x][1]]+key[x]+smx[ch[x][0]]);
smn[x]=min(smn[ch[x][1]],sum[ch[x][1]]+key[x]+smn[ch[x][0]]);
}
void Pushdown(int x){
if(lazy[x]&1){
Reverse(ch[x][0]); lazy[ch[x][0]]^=1;
Reverse(ch[x][1]); lazy[ch[x][1]]^=1;
lazy[x]^=1;
}
if(lazy[x]&2){
Flip(ch[x][0]); lazy[ch[x][0]]^=2;
Flip(ch[x][1]); lazy[ch[x][1]]^=2;
lazy[x]^=2;
}
}
void Rotate(int x,int &k){
static int y,z,l,r;
y=fa[x]; z=fa[y];
l=ch[y][0]!=x; r=l^1;
if(!z) k=x;
else ch[z][ch[z][0]!=y]=x;
fa[ch[x][r]]=y; fa[y]=x; fa[x]=z;
ch[y][l]=ch[x][r]; ch[x][r]=y;
Pushup(y);
}
void Splay(int x,int &k){
static int y,z;
while(x!=k){
y=fa[x]; z=fa[y];
if(y!=k) (ch[z][0]!=y)^(ch[y][0]!=x)?
Rotate(x,k):Rotate(y,k);
Rotate(x,k);
}
Pushup(x);
}
int find(int x,int num){
if(lazy[x]) Pushdown(x);
if(num<=siz[ch[x][0]]) return find(ch[x][0],num);
else if(num==siz[ch[x][0]]+1) return x;
else return find(ch[x][1],num-siz[ch[x][0]]-1);
}
int Split(int l,int r){
static int dl,dr;
dl=find(rt,l); dr=find(rt,r+2);
Splay(dl,rt); Splay(dr,ch[dl][1]);
return ch[dr][0];
}
void Modify(int l,int r,int type){
static int p;
p=Split(l,r);
if(type==1) Reverse(p);
else Flip(p);
lazy[p]^=type;
Pushup(fa[p]); Pushup(fa[fa[p]]);
}
void Build(int &x,int dad,int l,int r){
static char c;
if(l>r) return;
x=(l+r)>>1; fa[x]=dad;
Build(ch[x][0],x,l,x-1);
scanf(" %c",&c); key[x]=(c=='('?1:-1);
Build(ch[x][1],x,x+1,r);
Pushup(x);
}
void BorderBuild(){
rt=N+1;
key[N+1]=0; key[N+2]=0;
ch[N+1][1]=N+2; fa[N+2]=N+1;
Build(ch[N+2][0],N+2,1,N);
Pushup(N+2); Pushup(N+1);
}
int Query(int l,int r){
static int p,ANS,nl,nr;
p=Split(l,r);
nl=-pmn[p]; nr=smx[p];
ANS=(nl+1)/2+(nr+1)/2;
return ANS;
}
}DT;
int main(){
freopen("/home/noilinux/Documents/模块学习/2209.in","r",stdin);
scanf("%d%d",&N,&M);
DT.BorderBuild();
for(int i=1,c,l,r;i<=M;i++){
scanf("%d%d%d",&c,&l,&r);
if(c==0) printf("%d\n",DT.Query(l,r));
else DT.Modify(l,r,c);
}
return 0;
}

  

 

●BZOJ 2209 [Jsoi2011]括号序列的更多相关文章

  1. bzoj 2209: [Jsoi2011]括号序列 splay

    2209: [Jsoi2011]括号序列 Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 833  Solved: 392[Submit][Status ...

  2. BZOJ 2209: [Jsoi2011]括号序列 [splay 括号]

    2209: [Jsoi2011]括号序列 Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 1111  Solved: 541[Submit][Statu ...

  3. bzoj 2209 [Jsoi2011]括号序列 平衡树

    2209: [Jsoi2011]括号序列 Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 1404  Solved: 699[Submit][Statu ...

  4. 【BZOJ】2209: [Jsoi2011]括号序列(splay)

    http://www.lydsy.com/JudgeOnline/problem.php?id=2209 splay又犯逗........upd1那里的sum忘记赋值反............. 本题 ...

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

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

  6. BZOJ2209: [Jsoi2011]括号序列

    传送门 splay练习. 考虑把括号序列转化成类似于区间最大/最小值的情况. 显然我们可以知道括号序列消完的情况肯定是$a$个)和$b$个(,那么把这些括号全部合法化的代价显然就是$\frac{a+1 ...

  7. [HNOI2011]括号修复 / [JSOI2011]括号序列

    传送门 Solution 一道题花费了两天的时间-- 在大佬@PinkRabbit的帮助下,终于AC了,感动-- 首先,我们考虑一个括号序列被修改成合法序列需要的次数: 我们需要修改的其实是形如... ...

  8. 洛谷 P3215 [HNOI2011]括号修复 / [JSOI2011]括号序列(fhq-treap)

    题目链接 题意:有一个长度为 \(n\) 的括号序列,你需要支持以下操作: 将 \([l,r]\) 中所有括号变为 \(c\) 将 \([l,r]\) 区间翻转 将 \([l,r]\) 区间中左括号变 ...

  9. BZOJ2209 [Jsoi2011]括号序列 splay

    原文链接http://www.cnblogs.com/zhouzhendong/p/8093556.html 题目传送门 - BZOJ2209 题解 我太弱了,调出这题感觉都要吐了. 题解懒得写了. ...

随机推荐

  1. 团队作业4——第一次项目冲刺(Alpha版本)11.16

    a. 提供当天站立式会议照片一张 举行站立式会议,讨论项目安排: 整理各自的任务汇报: 全分享遇到的困难一起讨论: 讨论接下来的计划: b. 每个人的工作 (有work item 的ID) 1.前两天 ...

  2. 一个轻量级iOS安全框架:SSKeyChain

    摘要 SSKeyChains对苹果安全框架API进行了简单封装,支持对存储在钥匙串中密码.账户进行访问,包括读取.删除和设置.SSKeyChain的作者是大名鼎鼎的SSToolkit的作者samsof ...

  3. svn的使用技巧

    就是如果想一个文件在提交的时候不被上传,可以设置忽略这样提交的时候就不会被上传

  4. 初学深度学习(TensorFlow框架的心得and经验总结)自用环境的总结

    初学者的时间大部分浪费在了环境上了: 建议直接上Linux系统,我推荐国产的深度系统,deepin这几年一直在不断的发展,现在15.4已经很不错了 1,图形化界面很漂亮,内置正版crossover,并 ...

  5. 到底什么是 "method group"

    class Program { delegate void NoParam(); delegate void WithOneParam(string name); static void Main(s ...

  6. Groovy入门(2-2)Groovy的eclipse插件安装

    1.安装eclipse插件 启动eclipse,点击help -> Install New Software... 在弹出的窗口中点击:Add... Groovy插件的地址:http://dis ...

  7. redis入门(01)redis的下载和安装

    参考链接: 命令手册 : http://www.redis.net.cn/order/ 菜鸟教程: http://www.runoob.com/redis/redis-install.html 一.概 ...

  8. C# 解析json数据出现---锘縖

    解析json数据的时候出现 - 锘縖,不知道是不是乱码,反正我是不认识这俩字.后来发现是json的 '[' 字符转换的 网上搜了一下,说的是字符集不匹配,把字符集改为GB2312. 一.贴下处理jso ...

  9. C#Json转DataTable

    需求:有一个log文件,需要整理成Excel,日志文件里面的数据都是json字符串 思路是,把Json字符串转换成DataTable,然后导出到Excel 在网上找了一些资料,整理了以下三种类型的Js ...

  10. 重启Apache报错

    重启Apache报错,如图所示:server: /etc/httpd/modules/mod_jk.so: wrong ELF class: ELFCLASS64 原因:mod_jd的版本有问题 解决 ...