【BZOJ】2209: [Jsoi2011]括号序列(splay)
http://www.lydsy.com/JudgeOnline/problem.php?id=2209
splay又犯逗。。。。。。。。upd1那里的sum忘记赋值反。。。。。。。。。。。。。
本题好神。。首先发现将所有能匹配的消掉后一定是类似这样的))))((((,当然也有((((((这种情况
还有本题将查询的区间长度都看做偶数。。。。。
如果能知道有多少个)和多少个(,那么答案就是
)的个数除以2取上界+(的个数除以2取上界
很简单吧。。。。。。
所以我们只需要在splay维护从左边剩余的)最多有多少个,右边(最多有多少个即可。
但是由于操作2和操作3的存在,我们还需要维护左边剩余的(最多有多少个,右边)最多有多少个,这样就能支持了。。
然后请自己yy
#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <iostream>
#include <algorithm>
#include <queue>
#include <set>
#include <map>
using namespace std;
typedef long long ll;
#define rep(i, n) for(int i=0; i<(n); ++i)
#define for1(i,a,n) for(int i=(a);i<=(n);++i)
#define for2(i,a,n) for(int i=(a);i<(n);++i)
#define for3(i,a,n) for(int i=(a);i>=(n);--i)
#define for4(i,a,n) for(int i=(a);i>(n);--i)
#define CC(i,a) memset(i,a,sizeof(i))
#define read(a) a=getint()
#define print(a) printf("%d", a)
#define dbg(x) cout << (#x) << " = " << (x) << endl
#define error(x) (!(x)?puts("error"):0)
#define rdm(x, i) for(int i=ihead[x]; i; i=e[i].next)
inline const int getint() { int r=0, k=1; char c=getchar(); for(; c<'0'||c>'9'; c=getchar()) if(c=='-') k=-1; for(; c>='0'&&c<='9'; c=getchar()) r=r*10+c-'0'; return k*r; } const int oo=~0u>>1, N=1e5+10;
struct node *null;
struct node {
node *f, *c[2];
int s, k, lmin, lmax, rmin, rmax, sum;
bool tag, rev;
node(int _k=0) { s=1; lmin=lmax=rmin=rmax=k=sum=_k; f=c[0]=c[1]=null; tag=rev=0; }
void setc(node *x, bool d) { c[d]=x; x->f=this; }
bool d() { return f->c[1]==this; }
void pushup() {
s=c[0]->s+c[1]->s+1;
sum=c[0]->sum+c[1]->sum+k;
lmin=c[0]->lmin;
lmax=c[0]->lmax;
rmin=c[1]->rmin;
rmax=c[1]->rmax;
int mnl=min(0, c[1]->lmin), mnr=min(0, c[0]->rmin);
int mxl=max(0, c[1]->lmax), mxr=max(0, c[0]->rmax);
lmin=min(lmin, c[0]->sum+k+mnl);
lmax=max(lmax, c[0]->sum+k+mxl);
rmin=min(rmin, c[1]->sum+k+mnr);
rmax=max(rmax, c[1]->sum+k+mxr);
}
void upd1() {
if(this==null) return;
tag=!tag;
int t=lmin;
lmin=-lmax;
lmax=-t;
t=rmin;
rmin=-rmax;
rmax=-t;
k=-k;
sum=-sum;
}
void upd2() {
if(this==null) return;
rev=!rev;
swap(c[0], c[1]);
swap(lmin, rmin);
swap(lmax, rmax);
}
void pushdown() {
if(tag) {
tag=0;
c[0]->upd1();
c[1]->upd1();
}
if(rev) {
rev=0;
c[0]->upd2();
c[1]->upd2();
}
}
}*root;
void PN(node *x) {
printf("key:%c \t lmin:%d \t lmax:%d \t rmin:%d \t rmax:%d \t sum:%d \t \n", x->k==1?'(':(x->k==-1?')':'N'), x->lmin, x->lmax, x->rmin, x->rmax, x->sum);
}
void Pr(node *x) {
if(x==null) return;
Pr(x->c[0]);
if(x->k) printf("%c", x->k==1?'(':')');
Pr(x->c[1]);
}
void P(node *x=root) {
Pr(x); puts("");
}
void rot(node *x) {
node *f=x->f;
f->pushdown(); x->pushdown(); bool d=x->d();
f->f->setc(x, f->d());
f->setc(x->c[!d], d);
x->setc(f, !d);
f->pushup();
if(f==root) root=x;
}
void splay(node *x, node *f=null) {
x->pushdown();
while(x->f!=f)
if(x->f->f==f) rot(x);
else x->d()==x->f->d()?(rot(x->f), rot(x)):(rot(x), rot(x));
x->pushup();
}
node *sel(node *x, int k) {
if(x==null) return x;
x->pushdown();
int s=x->c[0]->s;
if(s==k) return x;
if(s<k) return sel(x->c[1], k-s-1);
return sel(x->c[0], k);
}
node *getrange(int l, int r) {
splay(sel(root, l-1));
splay(sel(root, r+1), root);
return root->c[1]->c[0];
}
void fix1() {
int l=getint(), r=getint();
node *x=getrange(l, r);
x->pushdown();
x->upd1();
}
void fix2() {
int l=getint(), r=getint();
node *x=getrange(l, r);
x->pushdown();
x->upd2();
}
void ask() {
int l=getint(), r=getint();
node *x=getrange(l, r);
l=(-x->lmin+1)>>1;
r=(x->rmax+1)>>1;
printf("%d\n", l+r);
} char s[N];
int n, m, q;
void build(int l, int r, node *&x) {
if(l>r) return;
int mid=(l+r)>>1;
x=new node(s[mid]==')'?-1:1);
if(l==r) return;
build(l, mid-1, x->c[0]);
build(mid+1, r, x->c[1]);
if(l<=mid-1) x->c[0]->f=x;
if(mid+1<=r) x->c[1]->f=x;
x->pushup();
}
void in(node *x) {
x->lmax=x->rmax=-oo;
x->lmin=x->rmin=oo;
x->sum=0;
x->k=0;
}
void init() {
null=new node(); null->s=0; in(null);
null->f=null->c[0]=null->c[1]=null;
root=new node(); in(root);
root->setc(new node(), 1); in(root->c[1]);
node *x;
read(n); read(m);
scanf("%s", s+1);
build(1, n, x);
root->c[1]->setc(x, 0);
root->c[1]->pushup();
root->pushup();
} int main() {
init();
while(m--) {
int c=getint();
if(c==0) ask();
else if(c==1) fix1();
else if(c==2) fix2();
}
return 0;
}
Description

Input
Output
Sample Input
)(())(
0 1 6
0 1 4
0 3 4
Sample Output
2
0
HINT
100%的数据满足N,Q不超过10^5
。
Source
【BZOJ】2209: [Jsoi2011]括号序列(splay)的更多相关文章
- 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 ...
- ●BZOJ 2209 [Jsoi2011]括号序列
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=2209 题解: Splay 很好的题,但是把智障的我给恶心到了... 首先不难发现,最后没 ...
- 【BZOJ2329/2209】[HNOI2011]括号修复/[Jsoi2011]括号序列 Splay
[BZOJ2329/2209][HNOI2011]括号修复/[Jsoi2011]括号序列 题解:我们的Splay每个节点维护如下东西:左边有多少多余的右括号,右边有多少多余的左括号,同时为了反转操作, ...
- BZOJ2209 [Jsoi2011]括号序列 splay
原文链接http://www.cnblogs.com/zhouzhendong/p/8093556.html 题目传送门 - BZOJ2209 题解 我太弱了,调出这题感觉都要吐了. 题解懒得写了. ...
- 【BZOJ-2329&2209】括号修复&括号序列 Splay
2329: [HNOI2011]括号修复 Time Limit: 40 Sec Memory Limit: 128 MBSubmit: 1007 Solved: 476[Submit][Statu ...
- BZOJ 2329/2209 [HNOI2011]括号修复 (splay)
题目大意: 让你维护一个括号序列,支持 1.区间修改为同一种括号 2.区间内所有括号都反转 3.翻转整个区间,括号的方向不变 4.查询把某段区间变为合法的括号序列,至少需要修改多少次括号 给跪了,足足 ...
- BZOJ 2329: [HNOI2011]括号修复( splay )
把括号序列后一定是))))((((这种形式的..所以维护一个最大前缀和l, 最大后缀和r就可以了..答案就是(l+1)/2+(r+1)/2...用splay维护,O(NlogN). 其实还是挺好写的, ...
随机推荐
- BeautifulSoup获取指定class样式的div
如何获取指定的标签的内容是解析网页爬取数据的必要手段,比如想获取<div class='xxx'> ...<div>这样的div标签,通常有三种办法, 1)用字符串查找方法,然 ...
- 使用nginx的proxy_cache做网站缓存
为什么要做web cache,我想大家最主要的是解决流量的压力.随着网站流量的提升,如果只是单台机器既处理静态文件,又处理动态脚本,显然效率很难上升,不能处理日益上涨的流量压力.与此同时某些网站的页面 ...
- 1.2 中国象棋将帅问题进一步讨论与扩展:如何用1个变量实现N重循环?[chinese chess]
[题目] 假设在中国象棋中只剩下将帅两个棋子,国人都知道基本规则:将帅不能出九宫格,只能上下左右移动,不能斜向移动,同时将帅不能照面.问在这样条件下,所有可能将帅位置.要求在代码中只能使用一个字节存储 ...
- Android runProguard配置 导致module lib 中的包编译时无法识别
今天写代码时用到了另一个lib型的工程,把它添加到dependencies后,在原工程中可以引用lib中的文件了,但是编译时就会报错,提示包不存在,后来在build.gradle中设置runProgu ...
- Linux卸载系统自带的JDK
安装Linux后,一般系统都会自带openjdk,我们开发中都需要自己安装,所以需要卸载之前的,以CentOS为例,卸载方法如下: 首先执行命令查看存在哪些已安装的包 rpm -qa | grep j ...
- js将map转换成数组
/** * map转数组. * * @param {Map}map * map对象 * @return 数组 */ Share.map2Ary = function(map) { var list = ...
- osgEarth例子
#include <osgViewer/Viewer>#include <osgViewer/ViewerEventHandlers>#include <osgGA/St ...
- 越狱后天气闪退 iPhone5天气闪退解决方法
iPhone5天气闪退解决方法: 第一步:前往Cydia卸载AppSync; 第二步:通过iTools删除/var/mobile/Library/Caches/com.apple.mobile.ins ...
- 关于printf函数输出先后顺序的讲解!!
对于printf函数printf("%d%d\n",a,b);函数的实际输出顺序是这样的先计算出b,然后在计算a,接着输出a,最后在输出b:例子如下:#include<ios ...
- register
register:这个关键字请求编译器尽可能的将变量存在CPU内部寄存器中,而不是通过内存寻址访问,以提高效率.注意是尽可能,不是绝对.你想想,一个CPU 的寄存器也就那么几个或几十个,你要是定义了很 ...