BZOJ2209: [Jsoi2011]括号序列
splay练习。
考虑把括号序列转化成类似于区间最大/最小值的情况。
显然我们可以知道括号序列消完的情况肯定是$a$个)和$b$个(,那么把这些括号全部合法化的代价显然就是$\frac{a+1}{2}+\frac{b+1}{2}$。
接着我们可以把'('变为1,把')'变为-1,然后每次取左区间的连续最小值,右区间的连续最大值,就是$a$与$b$的大小。
因为存在区间翻转,所以需要把左/右区间的连续最大/小值都搞出来。
splay即可。
//BZOJ2209 //by Cydiater //2017.2.15 #include <iostream> #include <iomanip> #include <cstring> #include <string> #include <queue> #include <map> #include <cmath> #include <ctime> #include <cstdlib> #include <cstdio> #include <algorithm> #include <bitset> #include <set> #include <vector> #include <complex> using namespace std; #define ll long long #define up(i,j,n) for(int i=j;i<=n;i++) #define down(i,j,n) for(int i=j;i>=n;i--) #define cmax(a,b) a=max(a,b) #define cmin(a,b) a=min(a,b) const int MAXN=1e5+5; const int oo=0x3f3f3f3f; inline int read(){ char ch=getchar();int x=0,f=1; while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int root,cnt=0,N,M,arr[MAXN]; char s[MAXN]; struct SplayTree{ int son[2],l0,l1,r0,r1,sum,fa,siz,tag0,tag1,val; }t[MAXN]; namespace solution{ inline int get(int k){return t[t[k].fa].son[1]==k;} inline void reload(int k){ int s1=t[k].son[0],s2=t[k].son[1]; t[k].l0=min(t[s1].l0,t[s1].sum+t[k].val+t[s2].l0); t[k].l1=max(t[s1].l1,t[s1].sum+t[k].val+t[s2].l1); t[k].r0=min(t[s2].r0,t[s2].sum+t[k].val+t[s1].r0); t[k].r1=max(t[s2].r1,t[s2].sum+t[k].val+t[s1].r1); t[k].siz=t[s1].siz+t[s2].siz+1; t[k].sum=t[s1].sum+t[s2].sum+t[k].val; } inline void push0(int k){ if(!k)return; swap(t[k].l0,t[k].l1);t[k].l0*=-1;t[k].l1*=-1; swap(t[k].r0,t[k].r1);t[k].r0*=-1;t[k].r1*=-1; t[k].tag0^=1;t[k].val*=-1;t[k].sum*=-1; } inline void push1(int k){ if(!k)return; swap(t[k].l0,t[k].r0); swap(t[k].l1,t[k].r1); t[k].tag1^=1; } inline void Pushdown(int k){ int s1=t[k].son[0],s2=t[k].son[1]; if(t[k].tag1){ push1(s1);push1(s2); swap(t[k].son[0],t[k].son[1]); t[k].tag1=0; } if(t[k].tag0){ push0(s1);push0(s2); t[k].tag0=0; } } inline void rotate(int k){ int old=t[k].fa,oldf=t[old].fa,which=get(k); t[old].son[which]=t[k].son[which^1];t[t[old].son[which]].fa=old; t[k].son[which^1]=old;t[old].fa=k; t[k].fa=oldf; if(oldf)t[oldf].son[t[oldf].son[1]==old]=k; reload(old);reload(k); } inline void splay(int k,int aim){ for(int fa;(fa=t[k].fa);rotate(k)){ if(k==aim)break; else if(fa==aim){ rotate(k); break; }else if(t[fa].fa==aim){ rotate(get(fa)==get(k)?fa:k); rotate(k); break; }else rotate(get(fa)==get(k)?fa:k); } if(aim==root)root=k; } int Node(int rnk){ int now=root; while(true){ Pushdown(now); int lsiz=t[now].son[0]?t[t[now].son[0]].siz:0; if(rnk<=lsiz)now=t[now].son[0]; else{ if(rnk==lsiz+1)return now; rnk-=lsiz+1; now=t[now].son[1]; } } } int Match(int L,int R){ int kl=Node(L),kr=Node(R+2); splay(kl,root);splay(kr,t[root].son[1]); return kr; } void Build(int L,int R,int &k,int fa){ if(!k)k=++cnt; int mid=(L+R)>>1; t[k].fa=fa;t[k].siz=1;t[k].tag0=t[k].tag1=0; t[k].l0=t[k].l1=t[k].r0=t[k].r1=0;t[k].val=arr[mid]; if(L==R){ t[k].son[0]=t[k].son[1]=0; t[k].sum=t[k].val; t[k].l0=t[k].l1=t[k].r0=t[k].r1=t[k].val; cmin(t[k].l0,0);cmin(t[k].r0,0); cmax(t[k].l1,0);cmax(t[k].r1,0); return; } if(L<=mid-1)Build(L,mid-1,t[k].son[0],k); if(mid+1<=R)Build(mid+1,R,t[k].son[1],k); reload(k); } int Col(int L,int R){ int k=Match(L,R); return ((t[t[k].son[0]].r1+1)/2)-((t[t[k].son[0]].l0-1)/2); } void Inv(int L,int R){ int k=Match(L,R); push0(t[k].son[0]); reload(k);reload(t[k].fa); } void Rev(int L,int R){ int k=Match(L,R); push1(t[k].son[0]); reload(k);reload(t[k].fa); } void Prepare(){ N=read();M=read(); scanf("%s",s+1); up(i,1,N)arr[i]=(s[i]=='('?1:-1); arr[0]=0;arr[N+1]=0; Build(0,N+1,root,0); } void Solve(){ //DEBUG(root); while(M--){ int op=read(),L=read(),R=read(); if(op==0)printf("%d\n",Col(L,R)); if(op==1)Inv(L,R); if(op==2)Rev(L,R); } } } int main(){ using namespace solution; Prepare(); Solve(); return 0; }
BZOJ2209: [Jsoi2011]括号序列的更多相关文章
- BZOJ2209 [Jsoi2011]括号序列 splay
原文链接http://www.cnblogs.com/zhouzhendong/p/8093556.html 题目传送门 - BZOJ2209 题解 我太弱了,调出这题感觉都要吐了. 题解懒得写了. ...
- bzoj 2209: [Jsoi2011]括号序列 splay
2209: [Jsoi2011]括号序列 Time Limit: 20 Sec Memory Limit: 259 MBSubmit: 833 Solved: 392[Submit][Status ...
- BZOJ 2209: [Jsoi2011]括号序列 [splay 括号]
2209: [Jsoi2011]括号序列 Time Limit: 20 Sec Memory Limit: 259 MBSubmit: 1111 Solved: 541[Submit][Statu ...
- bzoj 2209 [Jsoi2011]括号序列 平衡树
2209: [Jsoi2011]括号序列 Time Limit: 20 Sec Memory Limit: 259 MBSubmit: 1404 Solved: 699[Submit][Statu ...
- 【BZOJ2329/2209】[HNOI2011]括号修复/[Jsoi2011]括号序列 Splay
[BZOJ2329/2209][HNOI2011]括号修复/[Jsoi2011]括号序列 题解:我们的Splay每个节点维护如下东西:左边有多少多余的右括号,右边有多少多余的左括号,同时为了反转操作, ...
- 【BZOJ】2209: [Jsoi2011]括号序列(splay)
http://www.lydsy.com/JudgeOnline/problem.php?id=2209 splay又犯逗........upd1那里的sum忘记赋值反............. 本题 ...
- [HNOI2011]括号修复 / [JSOI2011]括号序列
传送门 Solution 一道题花费了两天的时间-- 在大佬@PinkRabbit的帮助下,终于AC了,感动-- 首先,我们考虑一个括号序列被修改成合法序列需要的次数: 我们需要修改的其实是形如... ...
- 洛谷 P3215 [HNOI2011]括号修复 / [JSOI2011]括号序列(fhq-treap)
题目链接 题意:有一个长度为 \(n\) 的括号序列,你需要支持以下操作: 将 \([l,r]\) 中所有括号变为 \(c\) 将 \([l,r]\) 区间翻转 将 \([l,r]\) 区间中左括号变 ...
- ●BZOJ 2209 [Jsoi2011]括号序列
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=2209 题解: Splay 很好的题,但是把智障的我给恶心到了... 首先不难发现,最后没 ...
随机推荐
- 【算法】深度优先搜索(DFS)III
1. DFS生成排列 众所周知,1,2…n的排列一共有n!个,因此生成全排列至少需要n!的时间复杂度.如果用循环来生成排列,当n稍大时,内外循环会非常之多.可以用DFS模拟解决,生成0 … n-1的排 ...
- React基础---->ReactJS的使用(一)
ReactJS的初次使用,比较简单的例子. React的使用 一.下载ReactJS,地址:http://reactjs.cn/react/downloads.html,直接解压就行. 二.在html ...
- hadoop 2.2.0集群安装详细步骤(简单配置,无HA)
安装环境操作系统:CentOS 6.5 i586(32位)java环境:JDK 1.7.0.51hadoop版本:社区版本2.2.0,hadoop-2.2.0.tar.gz 安装准备设置集群的host ...
- Docker源码分析(九):Docker镜像
1.前言 回首过去的2014年,大家可以看到Docker在全球刮起了一阵又一阵的“容器风”,工业界对Docker的探索与实践更是一波高过一波.在如今的2015年以及未来,Docker似乎并不会像其他昙 ...
- Java初学者笔记六:反射
Java反射基础 零.基础类代码 import java.io.*; import java.lang.reflect.*; class father{ public String fName; fa ...
- 【BZOJ4556】[Tjoi2016&Heoi2016]字符串 后缀数组+二分+主席树+RMQ
[BZOJ4556][Tjoi2016&Heoi2016]字符串 Description 佳媛姐姐过生日的时候,她的小伙伴从某东上买了一个生日礼物.生日礼物放在一个神奇的箱子中.箱子外边写了一 ...
- linux 程序启动与停止管理脚本
公司接了一个第三方的系统,基于linux写的几个程序,一共有9个部件,第三方没有给脚本,每次启动或停止都得一个一个手工去停止或修改.......,这里稍微鄙视下. 没办法,求人还不如自己动手写, 需求 ...
- Swift - 多线程GCD详解
// GCD详解 // 目录: // 1. 创建GCD队列(最常用) // 2. 自定义创建队列 // 3. 使用多线程实现延迟加载 // 4. 使用多线程实现重复(循环) // 5. ...
- 详解Go语言中的屏蔽现象
在刚开始学习Go语言的过程中,难免会遇到一些问题,尤其是从其他语言转向Go开发的人员,面对语法及其内部实现的差异,在使用Go开发时也避免不了会踩"坑".本文主要针对Go设计中的屏蔽 ...
- 【面向对象】----【prototype&&__proto__&&实例化对象三者之间的关系】(四)-----【巷子】
1.构造函数 a.什么是构造函数? 解释:通过关键字new 创建的函数叫做构造函数 作用:用来创建一个对象 废话少说直接上代码,首先我们还是创建一个构造函数人类 然后我们在创建两个实例,一个凡尘 一个 ...