2209: [Jsoi2011]括号序列

Time Limit: 20 Sec  Memory Limit: 259 MB
Submit: 833  Solved: 392
[Submit][Status]

Description

Input

输入数据的第一行包含两个整数N和Q,分别表示括号序列的长度,以及操作的个数。 第二行包含一个长度为N的括号序列。 接下来Q行,每行三个整数t、x和y,分别表示操作的类型、操作的开始位置和操作的结 束位置,输入数据保证x不小于y。其中t=0表示询问操作、t=1表示反转操作、t=2表示翻转操 作。

Output

对于每一个询问操作,输出一行,表示将括号序列的该子序列修改为配对,所需的最少改动 个数。

Sample Input

6 3
)(())(
0 1 6
0 1 4
0 3 4

Sample Output

2
2
0

HINT

100%的数据满足N,Q不超过10^5

  终于算是会写splay了,这道题涉及到splay的区间翻转,取反,询问以及lazy标记下放等操作,算是涵盖了splay的基本用法。

  合法的括号序列的一个性质是,以正括号为1,反括号为-1,合法序列和为0,且所有前缀权值和非负。顾可以通过类似于线段树求区间最大子段和方式维护,由于涉及到区间翻转,故改为splay维护。

  这次编写问题还是在标记同步上,具体来说,在get_kth()调用前一定要down(),修改子树后要讲修改后的值传回根节点。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAXN 210000
#define MAXT 210000
inline int min(int x,int y,int z)
{
return min(x,min(y,z));
}
inline int min(int a,int b,int c,int d)
{
return min(min(a,b),min(c,d));
}
inline int max(int x,int y,int z)
{
return max(x,max(y,z));
}
inline int max(int a,int b,int c,int d)
{
return max(max(a,b),max(c,d));
}
int num[MAXN];
struct splay_tree
{
int ch[MAXT][],pnt[MAXT];
int val[MAXT],siz[MAXT],sum[MAXT],lx[MAXT][],rx[MAXT][];
bool rev[MAXT],neg[MAXT];
int stack[MAXT],tops;
int topt;
int root;
splay_tree()
{
topt=,root=;
tops=-;
}
void reverse(int now)
{
if (!now)return;
swap(lx[now][],rx[now][]);
swap(lx[now][],rx[now][]);
swap(ch[now][],ch[now][]);
rev[now]^=;
}
void negate(int now)
{
if (!now)return ;
val[now]=-val[now];
sum[now]=-sum[now];
swap(lx[now][],lx[now][]);
swap(rx[now][],rx[now][]);
lx[now][]=-lx[now][];
rx[now][]=-rx[now][];
lx[now][]=-lx[now][];
rx[now][]=-rx[now][];
neg[now]^=;
}
void update(int now)
{
lx[now][]=min(lx[ch[now][]][],sum[ch[now][]],sum[ch[now][]]+val[now],sum[ch[now][]]+val[now]+lx[ch[now][]][]);
lx[now][]=max(lx[ch[now][]][],sum[ch[now][]],sum[ch[now][]]+val[now],sum[ch[now][]]+val[now]+lx[ch[now][]][]);
rx[now][]=min(rx[ch[now][]][],sum[ch[now][]],sum[ch[now][]]+val[now],sum[ch[now][]]+val[now]+rx[ch[now][]][]);
rx[now][]=max(rx[ch[now][]][],sum[ch[now][]],sum[ch[now][]]+val[now],sum[ch[now][]]+val[now]+rx[ch[now][]][]);
sum[now]=sum[ch[now][]]+sum[ch[now][]]+val[now];
siz[now]=siz[ch[now][]]+siz[ch[now][]]+;
}
void down(int now)
{
if (rev[now])
{
reverse(ch[now][]);
reverse(ch[now][]);
rev[now]=;
}
if (neg[now])
{
negate(ch[now][]);
negate(ch[now][]);
neg[now]=;
}
}
void rotate(int now)
{
int p=pnt[now],anc=pnt[p];
int dir=ch[p][]==now;
if (anc)
ch[anc][ch[anc][]==p]=now;
pnt[now]=anc;
pnt[ch[now][dir]]=p;
ch[p][-dir]=ch[now][dir];
pnt[p]=now;
ch[now][dir]=p;
update(p);
update(now);
}
void splay(int now,int tp=)
{
int x=now;
tops=-;
while (x!=tp)
{
stack[++tops]=x;
x=pnt[x];
}
while (~tops)
{
down(stack[tops--]);
}
while (now!=tp && pnt[now]!=tp)
{
int p=pnt[now],anc=pnt[p];
if (anc==tp)
rotate(now);
else if ((ch[p][]==now) == (ch[anc][]==p))
rotate(p),rotate(now);
else
rotate(now),rotate(now);
}
if (tp==)
root=now;
}
int get_kth(int now,int rk)
{
if (!now)throw ;
down(now);
if (siz[ch[now][]]+==rk)
return now;
if (siz[ch[now][]]+<rk)
return get_kth(ch[now][],rk-siz[ch[now][]]-);
else
return get_kth(ch[now][],rk);
}
void insert(int pos,int v)
{
if (!root)
{
root=++topt;
pnt[topt]=;
val[topt]=v;
update(topt);
}else if (!pos)
{
splay(get_kth(root,pos));
ch[root][]=topt;
pnt[topt]=root;
val[topt]=v;
update(topt);
update(root);
}else
{
splay(get_kth(root,pos));
val[++topt]=v;
pnt[topt]=root;
ch[topt][]=ch[root][];
pnt[ch[root][]]=topt;
ch[root][]=topt;
update(topt);
update(root);
}
}
int get_result(int now)
{
int res=,t;
t=-lx[now][];
res=t/+t%;
t=res*+sum[now];
res+=abs(t)/;
return res;
}
int query(int l,int r)
{
if (l== && r==siz[root])
return get_result(root);
if (l==)
{
splay(get_kth(root,r+));
return get_result(ch[root][]);
}
if (r==siz[root])
{
splay(get_kth(root,l-));
return get_result(ch[root][]);
}
splay(get_kth(root,r+));
splay(get_kth(root,l-),root);
return get_result(ch[ch[root][]][]);
}
void make_reverse(int l,int r)
{
if (l== && r==siz[root])
return reverse(root);
if (l==)
{
splay(get_kth(root,r+));
reverse(ch[root][]);
update(root);
return ;
}
if (r==siz[root])
{
splay(get_kth(root,l-));
reverse(ch[root][]);
update(root);
return ;
}
splay(get_kth(root,r+));
splay(get_kth(root,l-),root);
reverse(ch[ch[root][]][]);
update(ch[root][]);
update(root);
}
void make_negate(int l,int r)
{
if (l== && r==siz[root])
return negate(root);
if (l==)
{
splay(get_kth(root,r+));
negate(ch[root][]);
update(root);
return ;
}
if (r==siz[root])
{
splay(get_kth(root,l-));
negate(ch[root][]);
update(root);
return ;
}
splay(get_kth(root,r+));
splay(get_kth(root,l-),root);
negate(ch[ch[root][]][]);
update(ch[root][]);
update(root); }
void scan(int now)
{
if (!now)return ;
if (pnt[ch[now][]]!=now && ch[now][])throw ;
if (pnt[ch[now][]]!=now && ch[now][])throw ;
if (siz[now]!=siz[ch[now][]]+siz[ch[now][]]+)throw ;
scan(ch[now][]);
printf("%d ",val[now]);
scan(ch[now][]);
}
}pp;
int main()
{
//freopen("input.txt","r",stdin);
// freopen("output.txt","w",stdout);
int n,m,i,j,k,x,y,z;
scanf("%d%d\n",&n,&m);
char ch;
for (i=;i<=n;i++)
{
scanf("%c",&ch);
if (ch==')')
pp.insert(i-,-);
else
pp.insert(i-,);
}
int opt;
for (i=;i<=m;i++)
{
scanf("%d%d%d",&opt,&x,&y);
// pp.scan(pp.root);printf("\n");
if (opt==)
{
printf("%d\n",pp.query(x,y));
}else if (opt==)
{
pp.make_negate(x,y);
}else if (opt==)
{
pp.make_reverse(x,y);
}
}
}

bzoj 2209: [Jsoi2011]括号序列 splay的更多相关文章

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

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

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

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

  3. ●BZOJ 2209 [Jsoi2011]括号序列

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=2209 题解: Splay 很好的题,但是把智障的我给恶心到了...   首先不难发现,最后没 ...

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

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

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

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

  6. BZOJ2209 [Jsoi2011]括号序列 splay

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

  7. 【BZOJ-2329&2209】括号修复&括号序列 Splay

    2329: [HNOI2011]括号修复 Time Limit: 40 Sec  Memory Limit: 128 MBSubmit: 1007  Solved: 476[Submit][Statu ...

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

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

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

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

随机推荐

  1. 在JBoss中部署GeoServer

    GeoServer一直就不能在 JBoss应用服务器中正常部署.最近我在一个国外的论坛上找到了该问题的解决方案.以下方法经测试,可以将GeoServer 2.1.3 成功部署在 JBoss 5.0 和 ...

  2. java数组的拷贝四种方法:for、clone、System.arraycopy、arrays.copyof

    public class ArrayCopy{ public static void main(String []args){ int []a = {1,3,4,5}; toPrint(a); int ...

  3. request对象多种方法封装表单数据

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, ...

  4. spring注解:@PostConstruct和@PreDestroy

    关于在spring  容器初始化 bean 和销毁前所做的操作定义方式有三种: 第一种:通过@PostConstruct 和 @PreDestroy 方法 实现初始化和销毁bean之前进行的操作 第二 ...

  5. linux中的帮助命令 分类: linux 学习笔记 ubuntu 2015-07-05 19:07 31人阅读 评论(0) 收藏

    说实话,到目前为止我还是不太习惯使用linux自带的帮助文档,遇到问题都是去查我自己下载的chm格式的命令大全,不过这些帮助命令我们还是有必要了解的. 1.man [要查看的命令名称] 例如想要查看l ...

  6. HTML5 Canvas 2D绘图

    为了防止无良网站的爬虫抓取文章,特此标识,转载请注明文章出处.LaplaceDemon/ShiJiaqi. http://www.cnblogs.com/shijiaqi1066/p/4851774. ...

  7. SAMBA用户访问指定的目录

    指定某个用户访问一个特定的共享文件夹sfx 用户可以访问abc目录 别的用户不可以访问abc目录 先创建一个用户命令useradd sfx 创建一个smbpasswd用户 在创建这个用户时要先创建一个 ...

  8. mysql left用法

    LEFT(str,len) 返回字符串str的最左面len个字符. SELECT LEFT('123456789',5)

  9. BUG Error:Execution failed for task ':app:dexDebug'.

    Error:Execution failed for task ':app:dexDebug'. > com.android.ide.common.process.ProcessExceptio ...

  10. 如何获得Windows 8中已记住的WIFI的明文密码

    网上很流行的一种查看WIFI密码明文的方法,如下: 今天遇到了一种状况,就是如果不连WIFI的情况我能抓到这个密码吗?(实在不想开口问同事密码多少,只能苦逼的自己想办法了o(︶︿︶)o ) 答案当然是 ...