【hdu 5217】Brackets
Description
Miceren likes playing with brackets.
There are N brackets on his desk forming a sequence. In his spare time, he will do Q operations on this sequence, each operation is either of these two types:
1. Flip the X-th bracket, i.e. the X-th bracket will become ) if it is ( before, otherwise become ( .
2. In a given subsequence [L, R], query the K-th bracket position number after deleting all matched brackets. If the amount of brackets left is less than K, output -1. For example, if N = 10, L = 2, R = 9 and the sequence is ))(()))((). In the sub sequence [2, 9], the brackets sequence is )(()))((. After deleting all matched brackets, the sequence becomes ) )((. If K = 1, answer is 2. If K = 2, answer is 7. If K = 3, answer is 8. If K = 4, answer is 9. If K ≥ 5, answer is -1.
Miceren is good at playing brackets, instead of calculating them by himself.
As his friend, can you help him?
Input
The first line contains a single integer T, indicating the number of test cases.
Each test case begins with two integers N, Q, indicating the number of brackets in Miceren's desk and the number of queries.
Each of following Q lines describes an operation: if it is "1 X", it indicate the first type of operation. Otherwise it will be "2 L R K", indicating the second type of operation.
T is about 100.
1 ≤ N,Q ≤ 200000.
For each query, 1 ≤ X ≤ N and 1 ≤ L ≤ R ≤ N, 1 ≤ K ≤ N.
The ratio of test cases with N > 100000 is less than 10%.
Output
For each query operation, output the answer. If there is no K brackets left, output -1.
Sample Input
1
10 5
))(()))(()
2 2 9 2
2 2 9 3
2 2 9 5
1 3
2 2 9 5
Sample Output
7
8
-1
8
题意:给出一个括号序列和2种操作:1.翻转某一个括号;2.查询区间内完成括号匹配后第k个括号的原位置。($1\leq N,Q \leq 200000$)
分析:
易得,最后的序列一定形如 ')))(((' ,即左段皆为 ')',右段皆为 '(' 。我们可以建出一棵线段树,线段树上的每个节点对应区间内匹配后左段 '(' 的数量和右段 ')' 的数量。
区间合并与修改显然,主要问题在查询。至此我们可以通过查询区间[L,R]的信息快速得到第k个括号的类型。因为 '(' 在从右往左合并区间时单调不减, ')' 在从左往右合并区间时单调不减,所以可以在线段树上边跑边查询。详见代码。
- #include<cstdio>
- #include<algorithm>
- #include<cstring>
- #define lc x<<1
- #define rc x<<1|1
- #define LL long long
- using namespace std;
- const int N=5e5+;
- int T,n,m,op,L,R,x;
- int a[N],id[N],tl[N*],tr[N*];
- char ch[N];
- struct node{int t1,t0;}ans,now,tmp,t[N*];
- int read()
- {
- int x=,f=;char c=getchar();
- while(c<''||c>''){if(c=='-')f=-;c=getchar();}
- while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
- return x*f;
- }
- node merge(node a,node b)
- {
- node c=(node){a.t1,b.t0};
- if(a.t0>b.t1)c.t0+=a.t0-b.t1;
- else c.t1+=b.t1-a.t0;
- return c;
- }
- void build(int x,int l,int r)
- {
- tl[x]=l;tr[x]=r;
- if(l==r)
- {
- if(a[l])t[x]=(node){,};
- else t[x]=(node){,};
- id[l]=x;return;
- }
- int mid=(l+r)>>;
- build(lc,l,mid);
- build(rc,mid+,r);
- t[x]=merge(t[lc],t[rc]);
- }
- void modify(int x,int l,int r,int p)
- {
- if(l==r)
- {
- swap(t[x].t0,t[x].t1);
- return;
- }
- int mid=(l+r)>>;
- if(p<=mid)modify(lc,l,mid,p);
- else modify(rc,mid+,r,p);
- t[x]=merge(t[lc],t[rc]);
- }
- void query(int x,int l,int r)
- {
- if(L<=l&&r<=R)
- {
- ans=merge(ans,t[x]);
- return;
- }
- int mid=(l+r)>>;
- if(L<=mid)query(lc,l,mid);
- if(R>mid)query(rc,mid+,r);
- }
- int work0(int x,int l,int r,int goal)
- {
- if(l==r)return l;
- int mid=(l+r)>>;
- tmp=now;now=merge(t[rc],now);
- if(now.t0>=goal)
- {
- now=tmp;
- return work0(rc,mid+,r,goal);
- }
- return work0(lc,l,mid,goal);
- }
- int find0(int p,int goal)
- {
- int x=id[p];
- bool flag=false;
- now=merge(t[x],now);
- if(now.t0==goal)return p;
- if(x&)flag=true;
- while()
- {
- x>>=;
- if(flag)
- {
- tmp=now;now=merge(t[lc],now);
- if(now.t0>=goal){now=tmp;x=lc;break;}
- }
- if(x&)flag=true;
- else flag=false;
- }
- return work0(x,tl[x],tr[x],goal);
- }
- int work1(int x,int l,int r,int goal)
- {
- if(l==r)return l;
- int mid=(l+r)>>;
- tmp=now;now=merge(now,t[lc]);
- if(now.t1>=goal)
- {
- now=tmp;
- return work1(lc,l,mid,goal);
- }
- return work1(rc,mid+,r,goal);
- }
- int find1(int p,int goal)
- {
- int x=id[p];
- bool flag=true;
- now=merge(now,t[x]);
- if(now.t1==goal)return p;
- if(x&)flag=false;
- while()
- {
- x>>=;
- if(flag)
- {
- tmp=now;now=merge(now,t[rc]);
- if(now.t1>=goal){now=tmp;x=rc;break;}
- }
- if(x&)flag=false;
- else flag=true;
- }
- return work1(x,tl[x],tr[x],goal);
- }
- void work()
- {
- n=read();m=read();
- scanf("%s",ch+);
- for(int i=;i<=n;i++)
- if(ch[i]=='(')a[i]=;
- else a[i]=;
- build(,,n);
- while(m--)
- {
- op=read();
- if(op==)
- {
- x=read();
- modify(,,n,x);
- continue;
- }
- L=read();R=read();x=read();
- ans.t0=ans.t1=;
- query(,,n);
- if(ans.t0+ans.t1<x)
- {
- printf("-1\n");
- continue;
- }
- now.t0=now.t1=;
- if(x<=ans.t1)printf("%d\n",find1(L,x));
- else printf("%d\n",find0(R,ans.t0+ans.t1-x+));
- }
- }
- int main()
- {
- T=read();
- while(T--)work();
- return ;
- }
【hdu 5217】Brackets的更多相关文章
- 【HDU 5184】 Brackets (卡特兰数)
Brackets Problem Description We give the following inductive definition of a “regular brackets” sequ ...
- 【数位dp】【HDU 3555】【HDU 2089】数位DP入门题
[HDU 3555]原题直通车: 代码: // 31MS 900K 909 B G++ #include<iostream> #include<cstdio> #includ ...
- 【HDU 5647】DZY Loves Connecting(树DP)
pid=5647">[HDU 5647]DZY Loves Connecting(树DP) DZY Loves Connecting Time Limit: 4000/2000 MS ...
- -【线性基】【BZOJ 2460】【BZOJ 2115】【HDU 3949】
[把三道我做过的线性基题目放在一起总结一下,代码都挺简单,主要就是贪心思想和异或的高斯消元] [然后把网上的讲解归纳一下] 1.线性基: 若干数的线性基是一组数a1,a2,a3...an,其中ax的最 ...
- 【HDU 2196】 Computer(树的直径)
[HDU 2196] Computer(树的直径) 题链http://acm.hdu.edu.cn/showproblem.php?pid=2196 这题可以用树形DP解决,自然也可以用最直观的方法解 ...
- 【HDU 2196】 Computer (树形DP)
[HDU 2196] Computer 题链http://acm.hdu.edu.cn/showproblem.php?pid=2196 刘汝佳<算法竞赛入门经典>P282页留下了这个问题 ...
- 【HDU 5145】 NPY and girls(组合+莫队)
pid=5145">[HDU 5145] NPY and girls(组合+莫队) NPY and girls Time Limit: 8000/4000 MS (Java/Other ...
- 【hdu 1043】Eight
[题目链接]:http://acm.hdu.edu.cn/showproblem.php?pid=1043 [题意] 会给你很多组数据; 让你输出这组数据到目标状态的具体步骤; [题解] 从12345 ...
- 【HDU 3068】 最长回文
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=3068 [算法] Manacher算法求最长回文子串 [代码] #include<bits/s ...
随机推荐
- KindEditor富文本编辑器使用
我的博客本来打算使用layui的富文本编辑器,但是出了一个问题,无法获取编辑器内容,我参考官方文档,获取内容也就那几个方法而已,但是引入进去后始终获取的值为空,百度和bing都试过了,但是始终还是获取 ...
- 实验吧 简单的SQL注入1
解题链接:http://ctf5.shiyanbar.com/423/web/ 解题思路:一, 输入1,不报错:输入1',报错:输入1'',不报错. 二 , 输入1 and 1=1,返回1 1 ...
- ksar、sar及相关内核知识点解析
关键词:sar.sadc.ksar./proc/stat./proc/cpuinfo./proc/meminfo./proc/diskstats. 在之前有简单介绍过sar/ksar,最近在使用中感觉 ...
- Kubernetes(基础 一):进程
容器其实是一种沙盒技术.顾名思义,沙盒就是能够像一个集装箱一样,把你的应用“装”起来的技术.这样,应用与应用之间,就因为有了边界而不至于相互干扰:而被装进集装箱的应用,也可以被方便地搬来搬去,这不就是 ...
- mysql之优化(2)
1.选取最适用的字段属性MySQL可以很好的支持大数据量的存取,但是一般说来,数据库中的表越小,在它上面执行的查询也就会越快.因此,在创建表的时候,为了获得更好的性能,我们可以将表中字段的宽度设得尽可 ...
- WPF中利用控件的DataContext属性为多个TextBox绑定数据
工作上需要从给定的接口获取数据,然后显示在界面的编辑框中,以往肯定会一个一个的去赋值,但这样太麻烦而且效率很低,不利于维护,于是想到了数据绑定这一方法,数据绑定主要利用INotifyPropertyC ...
- Tensorflow--矩阵切片与连接
博客转载自:https://blog.csdn.net/davincil/article/details/77893185 函数原型:slice(input_, begin, size, name=N ...
- Announcing Microsoft Research Open Data – Datasets by Microsoft Research now available in the cloud
The Microsoft Research Outreach team has worked extensively with the external research community to ...
- git 学习(2) ----- 分支
当我们进行程序开发的过程中,有时会产生一个新的想法,然后就想马上试验,那我们怎么办? 如果我们继续在现有的基础上进行开发,但最后想法不成功,我们还要进行版本回退?如果我们的新想法,需要很长时间才能实现 ...
- jsp篇 之 Jsp中的内置对象和范围对象
Jsp中的内置对象: 在jsp页面代码中不需要声明,直接可以使用的对象. 一共有[9个内置对象]可以直接使用. 对象类型 名字 PageContext pageC ...