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的更多相关文章

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

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

  2. 【数位dp】【HDU 3555】【HDU 2089】数位DP入门题

    [HDU  3555]原题直通车: 代码: // 31MS 900K 909 B G++ #include<iostream> #include<cstdio> #includ ...

  3. 【HDU 5647】DZY Loves Connecting(树DP)

    pid=5647">[HDU 5647]DZY Loves Connecting(树DP) DZY Loves Connecting Time Limit: 4000/2000 MS ...

  4. -【线性基】【BZOJ 2460】【BZOJ 2115】【HDU 3949】

    [把三道我做过的线性基题目放在一起总结一下,代码都挺简单,主要就是贪心思想和异或的高斯消元] [然后把网上的讲解归纳一下] 1.线性基: 若干数的线性基是一组数a1,a2,a3...an,其中ax的最 ...

  5. 【HDU 2196】 Computer(树的直径)

    [HDU 2196] Computer(树的直径) 题链http://acm.hdu.edu.cn/showproblem.php?pid=2196 这题可以用树形DP解决,自然也可以用最直观的方法解 ...

  6. 【HDU 2196】 Computer (树形DP)

    [HDU 2196] Computer 题链http://acm.hdu.edu.cn/showproblem.php?pid=2196 刘汝佳<算法竞赛入门经典>P282页留下了这个问题 ...

  7. 【HDU 5145】 NPY and girls(组合+莫队)

    pid=5145">[HDU 5145] NPY and girls(组合+莫队) NPY and girls Time Limit: 8000/4000 MS (Java/Other ...

  8. 【hdu 1043】Eight

    [题目链接]:http://acm.hdu.edu.cn/showproblem.php?pid=1043 [题意] 会给你很多组数据; 让你输出这组数据到目标状态的具体步骤; [题解] 从12345 ...

  9. 【HDU 3068】 最长回文

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=3068 [算法] Manacher算法求最长回文子串 [代码] #include<bits/s ...

随机推荐

  1. python Socket socketserver

    Socket 套接字 socket的 类型 实现socket对象时传入 到socket 类中 socket.AF_INET 服务器间的通讯 IPv4 socket.AF_INET6 IPv6 sock ...

  2. mysql 相关命令

    1.mysql导入导出 导出 进入到mysql bin目录 导出表 ./mysqldump -uroot -p --socket=/wdcloud/app/mysql1/temp/mysql.sock ...

  3. day14- 面向对象基础(一)

    今天开始写关于面向对象的内容,面向对象是编程思想中一大思想,由于日常使用中经常会用到,本次主要是对于我个人认为重点的基础知识进行整理,不会特别详细的书写. 1.面向过程与面向对象的区别 2.类 3.类 ...

  4. ESP8266产品ID

    ESP.getChipId() https://github.com/espressif/arduino-esp32/blob/master/libraries/ESP32/examples/Chip ...

  5. Autoware(2)—加载地图数据

    选择Point cloud.Ref选择.autoware/.data/map/pointcloud_map/里面的全选 点Point cloud加载 vector Map和TF同理

  6. MySQL索引原理及慢查询优化(转自:美团tech)

    背景 MySQL凭借着出色的性能.低廉的成本.丰富的资源,已经成为绝大多数互联网公司的首选关系型数据库.虽然性能出色,但所谓“好马配好鞍”,如何能够更好的使用它,已经成为开发工程师的必修课,我们经常会 ...

  7. jmeter学习记录--07--jmeter元件

    通过jmeter元件可以模拟负载.参数化.设置关联.设置检查点.设置集合点.控制场景运行.监控测试结果等. 1.逻辑控制器:比如foreach控制器,查询到了订单并要对每个订单进行出库操作,以订单号作 ...

  8. java的List列表转成Tree(树形)结构列表

    直接看借鉴博客:https://blog.csdn.net/massivestars/article/details/53911620/ 由于我的业务没有父子级id两个字段,只有一个层级id字段来分层 ...

  9. Package与Activity简介

    Package Package 包.只是在我们的app中这个Package是唯一的,就像你身份证号码一样.在我们做app自动化时,我们就需要知道他的Package,我们知道了Package那么也就知道 ...

  10. Python——序列化模块

    #json 模式 1.dumps.loads  方法 针对内存 dic = {'k1':'v1'} #转换成json import json str_d = json.dumps(dic) #序列化 ...