题意:给你一个括号序列。操作1:询问需要更改多少个括号使之匹配。

操作2:反转序列,左括号变成右括号。

操作3:翻转序列,倒置。

标程:

 #include<cstdio>
#include<algorithm>
#include<cstring>
#define ls son[k][0]
#define rs son[k][1]
using namespace std;
const int N=;
int sum[N],mn_l[N],mx_l[N],mx_r[N],mn_r[N],a[N],son[N][],rev[N],tag[N],n,t,l,r,sz[N],y,z,fa[N],Q,rt;
char s[N];
void up(int k)
{
sum[k]=sum[ls]+sum[rs]+a[k];sz[k]=sz[ls]+sz[rs]+;
mx_l[k]=max(mx_l[ls],sum[ls]+a[k]+mx_l[rs]);
mn_l[k]=min(mn_l[ls],sum[ls]+a[k]+mn_l[rs]);
mx_r[k]=max(mx_r[rs],sum[rs]+a[k]+mx_r[ls]);
mn_r[k]=min(mn_r[rs],sum[rs]+a[k]+mn_r[ls]);
}
void work_rev(int k)//由于需要访问实际pushdown到点的下一层(son[r+1][0]),所以要对下一层的权值进行修改
{rev[k]^=;swap(mx_l[k],mx_r[k]);swap(mn_l[k],mn_r[k]);}
void work_opp(int k)
{
tag[k]^=;
sum[k]=-sum[k];a[k]=-a[k];
mx_l[k]=-mx_l[k];mx_r[k]=-mx_r[k];mn_l[k]=-mn_l[k];mn_r[k]=-mn_r[k];
swap(mx_l[k],mn_l[k]);swap(mx_r[k],mn_r[k]);
}
void down(int k)
{
if (rev[k])
{
swap(son[k][],son[k][]);work_rev(ls);work_rev(rs);
rev[k]=;
}
if (tag[k])
{
work_opp(ls);work_opp(rs);
tag[k]=;
}
}
void rot(int &k,int x)
{
int y=fa[x],z=fa[y],l=(son[y][]==x),r=l^;//函数里面定义l,r,不要和询问的l,r混淆
if (y==k) k=x;else son[z][(son[z][]==y)]=x;
fa[y]=x;fa[x]=z;fa[son[x][r]]=y;
son[y][l]=son[x][r];son[x][r]=y;
up(y);up(x);
}
void spl(int &k,int x)
{
for (;x!=k;rot(k,x))
if ((y=fa[x])!=k)
if (son[y][]==x^son[fa[y]][]==y) rot(k,x);else rot(k,y);
}
void build(int l,int r,int f)
{
if (l>r) return;
int mid=(l+r)>>;fa[mid]=f;
if (f) son[f][(mid>f)]=mid;
if (s[mid]=='(') a[mid]=;else if (s[mid]==')') a[mid]=-;
if (l==r)
{
sz[l]=;sum[l]=a[l];
if (a[l]>) mx_l[l]=mx_r[l]=;
if (a[l]<) mn_l[l]=mn_r[l]=-;
return;
}
build(l,mid-,mid);build(mid+,r,mid);
up(mid);
}
int find(int k,int x)//因为有翻转操作,所以区间第x个与原下标为x的不对应
{
down(k);
if (x==sz[ls]+) return k;
if (x<=sz[ls]) return find(ls,x);else return find(rs,x-sz[ls]-);
}
int main()
{
scanf("%d%d%s",&n,&Q,s+);s[]='*';s[n+]='*';
build(,n+,);rt=(n+)/;
while (Q--)
{
scanf("%d%d%d",&t,&l,&r);
l=find(rt,l);r=find(rt,r+);
spl(rt,l);spl(son[rt][],r); int now=son[r][];
if (t==) printf("%d\n",(abs(mn_l[now])+)/+(abs(mx_r[now])+)/);
else if (t==) work_opp(now);
else work_rev(now);
}
return ;
}

易错点:1.由于需要访问实际pushdown到点的下一层(son[r+1][0]),所以要对下一层的权值进行修改 。pushdown的写法应根据实际情况来。

2.函数里面定义l,r,不要和询问的l,r混淆。

3.因为有翻转操作,所以区间第x个与原下标为x的不对应。所以要find到区间第x个数(二叉排序树维护区间位置)。

题解:splay

你看有翻转为什么不用splay呢?

对于一串括号序列,将中间的匹配掉后剩下x个右括号和y个左括号。(x+y)是偶数时才可能完全匹配。此时如果x,y全偶,那么修改x/2+y/2个即可,全奇,修改(x+1)/2+(y+1)/2个即可。问题在于怎么求x和y。

有性质,x=由左端点固定,右端点在[l,r]中的括号子序列中(右括号-左括号)的最大值,y=由右端点固定,左端点在[l,r]中的括号子序列中(左括号-右括号)的最大值。

用+1-1表示左右括号,x=左边最大,y=右边最小。

反转,就需要维护再维护左边最小和右边最大。用打标记的方法,标记下传时对四个关键值取负,并把左边/右边的最小最大交换。

翻转维护rev标记即可。

bzoj2209 括号序列的更多相关文章

  1. BZOJ2209: [Jsoi2011]括号序列

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

  2. BZOJ4350: 括号序列再战猪猪侠

    Description 括号序列与猪猪侠又大战了起来. 众所周知,括号序列是一个只有(和)组成的序列,我们称一个括号 序列S合法,当且仅当: 1.( )是一个合法的括号序列. 2.若A是合法的括号序列 ...

  3. DP专题——括号序列

    毕竟是个渣,写完一遍之后又按LRJ的写了一遍,再写了一遍递归版,最终加上输出解部分 括号序列 定义如下规则序列(字符串): 空序列是规则序列: 如果S是规则序列,那么(S)和[S]也是规则序列: 如果 ...

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

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

  5. 51nod1476 括号序列的最小代价

    这题应该可以用费用流写吧?不过我想不出贪心来TAT.其实还是单调队列乱搞啊T_T //ÍøÉϵÄ̰ÐÄËã·¨ºÃÉñ°¡¡£¡£¡£ÎÒÖ»»áÓÃ×îС·ÑÓÃ×î´óÁ÷ÅÜTAT #in ...

  6. lintcode: 有效的括号序列

    题目: 有效的括号序列 给定一个字符串所表示的括号序列,包含以下字符: '(', ')', '{', '}', '[' and']', 判定是否是有效的括号序列. 样例 括号必须依照 "() ...

  7. uoj #31. 【UR #2】猪猪侠再战括号序列 贪心

    #31. [UR #2]猪猪侠再战括号序列 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://uoj.ac/problem/31 Descript ...

  8. bzoj 1095 [ZJOI2007]Hide 捉迷藏(括号序列+线段树)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1095 [题意] 给定一棵树,树上颜色或白或黑而且可以更改,多个询问求最远黑点之间的距离 ...

  9. CODEVS 3657 括号序列

    [问题描述] 我们用以下规则定义一个合法的括号序列: (1)空序列是合法的 (2)假如S是一个合法的序列,则 (S) 和[S]都是合法的 (3)假如A 和 B 都是合法的,那么AB和BA也是合法的 例 ...

随机推荐

  1. Java-Class-I:java.util.List

    ylbtech-Java-Class-I:java.util.List 1.返回顶部 1.1.import java.util.ArrayList;import java.util.List; 1.2 ...

  2. Model Maker上手指南

    Model Maker上手指南 目录 1.MM可爱的脸 2.MM中的工程Project 3.新建类图 4.添加类成员 5.实现类的方法 6.生成Delphi代码 7.逆向到模型 8.完全的逆向工程 作 ...

  3. 最详尽使用指南:超快上手Jupyter Notebook

    最详尽使用指南:超快上手Jupyter Notebook - CSDN博客https://blog.csdn.net/DataCastle/article/details/78890469

  4. 4、postman的常见断言

    推荐我的另一篇文章  浅谈JSONObject解析JSON数据,这篇文章原理类似,使用java或者beanshell进行断言解析json数据 介绍断言之前,我们先测试1个接口: 接口地址:https: ...

  5. 《DSP using MATLAB》Problem 8.43

    代码: %% ------------------------------------------------------------------------ %% Output Info about ...

  6. spark2.+ sql 性能调优

    1.在内存中缓存数据 性能调优主要是将数据放入内存中操作,spark缓存注册表的方法 版本 缓存 释放缓存 spark2.+ spark.catalog.cacheTable("tableN ...

  7. 【6折抢】戴尔i7新品Latitude高性能商用本

    致敬拼搏成长中的企业 戴尔5月有钜惠! 买1赠1送同款,单台价格2500元 这波来自戴尔官网的致敬很走心 满足初级办公和高性能运算多重需求 限时折扣火热开抢! 新品  latitude 6折抢! 戴尔 ...

  8. VO和DO的区别

    阿里巴巴Java开发手册中的DO.DTO.BO.AO.VO.POJO定义 分层领域模型规约: DO( Data Object):与数据库表结构一一对应,通过DAO层向上传输数据源对象. DTO( Da ...

  9. 大道浮屠诀---mysql5.7.28 for linux安装

    环境: redhat6.5 MySQL Community Server 5.7.28 https://dev.mysql.com/downloads/mysql/5.7.html 安装RMP包的具体 ...

  10. Number Sequence /// oj21456

    题目大意: 有一组规律数 the first 80 digits of the sequence are as follows: 1 12 123 1234 12345 123456 1234567 ...