【题意概述】

  给出一个有左括号和右括号的序列,左边的左括号和右边的右括号可以合并。现在要求你维护这个序列,支持两种操作:

  1,翻转某个位置的括号;

  2,查询区间[L,R]合并后第k个括号在原序列中的位置,如果k超过区间合并后的括号总数,输出-1.

【题解】

  首先我们可以发现,对于一个区间,合并后的结果一定是若干个右括号、若干个左括号的形式。即))))(((((...

  线段树上维护两个标记,区间左边的右括号数量cl、区间右边的左括号数量cr。合并的时候把左区间的cr和右区间的cl抵消一下,然后计算新的cl、cr即可。

  这样对于询问,我们可以快速确定它是左括号还是右括号,或者不满足题意输出-1。但我们怎么求第k个左/右括号在原序列中的位置呢?我的做法是询问的时候把经过的各个区间记录一下,逐个区间查找,如果k落在当前区间,就进入线段树进行查找,走到叶子结点就是答案。也可以直接在线段树上查找,不把区间取出来。

  

 #include<cstdio>
#include<algorithm>
#define rg register
#define N 200010
#define ls (u<<1)
#define rs (u<<1|1)
using namespace std;
int T,n,m,f[N],s[N],cnt,rt;
char c[N];
struct tree{
int l,r,cl,cr;
}a[N<<];
struct rec{
int cl,cr;
};
inline int read(){
int k=; char c=getchar();
while(c<''||c>'')c=getchar();
while(''<=c&&c<='')k=k*+c-'',c=getchar();
return k;
}
inline void pushup(int u){
a[u].cl=a[ls].cl; a[u].cr=a[rs].cr;
int tmp=a[ls].cr-a[rs].cl;
if(tmp>) a[u].cr+=tmp;
else a[u].cl-=tmp;
}
void build(int u,int l,int r){
a[u].l=l; a[u].r=r; a[u].cl=a[u].cr=;
if(l<r){
int mid=(l+r)>>;
build(ls,l,mid); build(rs,mid+,r);
pushup(u);
}
else{
if(f[l]==) a[u].cr=; else a[u].cl=;
}
}
void update(int u,int pos){
if(a[u].l==a[u].r){
a[u].cl^=; a[u].cr^=; return;
}
int mid=(a[u].l+a[u].r)>>;
if(pos<=mid) update(ls,pos);
else update(rs,pos);
pushup(u);
}
rec query(int u,int l,int r){
if(l<=a[u].l&&a[u].r<=r){
s[++cnt]=u;
rec tmp;
tmp.cl=a[u].cl; tmp.cr=a[u].cr;
return tmp;
}
int mid=(a[u].l+a[u].r)>>;
rec ret,L,R; ret.cl=ret.cr=;
if(l<=mid) ret=L=query(ls,l,r);
if(r>mid) ret=R=query(rs,l,r);
if(l<=mid&&r>mid){
ret.cl=L.cl; ret.cr=R.cr;
int tmp=L.cr-R.cl;
if(tmp>) ret.cr+=tmp;
else ret.cl-=tmp;
}
return ret;
}
int findl(int u,int k){
if(a[u].l==a[u].r) return a[u].l;
if(a[ls].cl>=k) return findl(ls,k);
return findl(rs,k-a[ls].cl+a[ls].cr);
}
int findr(int u,int k){
if(a[u].l==a[u].r) return a[u].l;
if(a[rs].cr>=k) return findr(rs,k);
return findr(ls,k-a[rs].cr+a[rs].cl);
}
int main(){
T=read();
while(T--){
n=read(); m=read();
scanf("%s",c+);
for(rg int i=;i<=n;i++) if(c[i]=='(') f[i]=; else f[i]=;
build(,,n);
while(m--){
int opt=read();
if(opt==){
int x=read();
update(,x);
}
else{
int l=read(),r=read(),k=read(); cnt=;
rec tmp=query(,l,r);
if(tmp.cl+tmp.cr<k){
puts("-1");
continue;
}
if(tmp.cl>=k){
for(rg int i=;i<=cnt;i++){
if(a[s[i]].cl>=k){
rt=s[i]; break;
}
else k+=a[s[i]].cr-a[s[i]].cl;
}
printf("%d\n",findl(rt,k));
}
else{
k=tmp.cl+tmp.cr-k+;
for(rg int i=cnt;i;i--){
if(a[s[i]].cr>=k){
rt=s[i]; break;
}
else k+=a[s[i]].cl-a[s[i]].cr;
}
printf("%d\n",findr(rt,k));
}
}
}
}
return ;
}

HDU 5217 Brackets的更多相关文章

  1. 【hdu 5217】Brackets

    Description Miceren likes playing with brackets. There are N brackets on his desk forming a sequence ...

  2. 2015 "BestCoder Cup" Champion

    这场比赛我没有参加,不过就算参加了也估计是被完虐.于是看着题解把大部分题目都搞了一遍. T1:Movie(hdu 5214) 题目大意: 给出N个区间,问能否选出3个互不相交的区间. N<=10 ...

  3. BestCoder Round #32

    问题描述 目前,我们用PM2.5的含量来描述空气质量的好坏.一个城市的PM2.5含量越低,它的空气质量就越好.所以我们经常按照PM2.5的含量从小到大对城市排序.一些时候某个城市的排名可能上升,但是他 ...

  4. 【HDU 5184】 Brackets (卡特兰数)

    Brackets Problem Description We give the following inductive definition of a “regular brackets” sequ ...

  5. HDU——PKU题目分类

    HDU 模拟题, 枚举1002 1004 1013 1015 1017 1020 1022 1029 1031 1033 1034 1035 1036 1037 1039 1042 1047 1048 ...

  6. HDU 1866 A + B forever!

    A + B forever! Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) T ...

  7. HDOJ 2111. Saving HDU 贪心 结构体排序

    Saving HDU Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  8. 【HDU 3037】Saving Beans Lucas定理模板

    http://acm.hdu.edu.cn/showproblem.php?pid=3037 Lucas定理模板. 现在才写,noip滚粗前兆QAQ #include<cstdio> #i ...

  9. hdu 4859 海岸线 Bestcoder Round 1

    http://acm.hdu.edu.cn/showproblem.php?pid=4859 题目大意: 在一个矩形周围都是海,这个矩形中有陆地,深海和浅海.浅海是可以填成陆地的. 求最多有多少条方格 ...

随机推荐

  1. 洛谷P2680 运输计划——树上差分

    题目:https://www.luogu.org/problemnew/show/P2680 久违地1A了好高兴啊! 首先,要最大值最小,很容易想到二分: 判断当前的 mid 是否可行,需要看看有没有 ...

  2. uva1563

    https://vjudge.net/problem/UVA-1563 高斯消元解同余方程组 就是把原来的除法换成逆元,其他的都一样 #include<bits/stdc++.h> usi ...

  3. MQTT + apache-apollo服务器初学使用

    说明:MQTT是IBM开发的一个即时通讯协议,有可能成为物联网的重要组成部分.该协议支持所有平台,几乎可以把所有联网物品和外部连接起来,被用来当做传感器和致动器(比如通过Twitter让房屋联网)的通 ...

  4. bzoj [Usaco2010 Hol]cowpol 奶牛政坛【树链剖分】

    意识流虚树 首先考虑只有一个党派,那么可以O(n)求树的直径,步骤是随便指定一个根然后找距离根最远点,然后再找距离这个最远点最远的点,那么最远点和距离这个最远点最远的点之间的距离就是直径 那么考虑多党 ...

  5. http升级https(转)

    让你的网站免费支持 HTTPS 及 Nginx 平滑升级 为什么要使用 HTTPS ? 首先来说一下 HTTP 与 HTTPS 协议的区别吧,他们的根本区别就是 HTTPS 在 HTTP 协议的基础上 ...

  6. ASP.NET MVC5 之 分部页

    1.分部页 _PartialPage.cshtml @model List<string> <a>完美世界</a> @foreach (var item in Mo ...

  7. IIS 相关配置

    IIS 和 VS 安装顺序 正常情况是先装IIS,后装VS:这样就不会发生错误了,因为asp.net就可以注册写入到IIS中.如果先装VS,再装IIS,这样就会导致"访问IIS元数据库失败& ...

  8. 计算科学(转自wiki)

    计算科学(也称科学计算 scientific computation 或 SC)是一个快速增长的多学科领域,使用先进的计算能力来理解和解决复杂的问题. 计算科学包括三个不同的方面: 1. 开发用于解决 ...

  9. 385 Mini Parser 迷你解析器

    Given a nested list of integers represented as a string, implement a parser to deserialize it.Each e ...

  10. 274 H-Index H指数

    给定一位研究者的论文被引用次数的数组(被引用次数是非负整数).写一个方法计算出研究者的H指数.H-index定义: “一位科学家有指数 h 是指他(她)的 N 篇论文中至多有 h 篇论文,分别被引用了 ...