Flipping Parentheses

题目连接:

http://codeforces.com/gym/100803/attachments

Description

A string consisting only of parentheses ‘(’ and ‘)’ is called balanced if it is one of the following.

• A string “()” is balanced.

• Concatenation of two balanced strings are balanced.

• When a string s is balanced, so is the concatenation of three strings “(”, s, and “)” in this

order.

Note that the condition is stronger than merely the numbers of ‘(’ and ‘)’ are equal. For instance,

“())(()” is not balanced.

Your task is to keep a string in a balanced state, under a severe condition in which a cosmic ray

may flip the direction of parentheses.

You are initially given a balanced string. Each time the direction of a single parenthesis is

flipped, your program is notified the position of the changed character in the string. Then,

calculate and output the leftmost position that, if the parenthesis there is flipped, the whole

string gets back to the balanced state. After the string is balanced by changing the parenthesis

indicated by your program, next cosmic ray flips another parenthesis, and the steps are repeated

several times

Input

The input consists of a single test case formatted as follows.

The first line consists of two integers N and Q (2 ≤ N ≤ 300000, 1 ≤ Q ≤ 150000). The second

line is a string s of balanced parentheses with length N. Each of the following Q lines is an

integer qi (1 ≤ qi ≤ N) that indicates that the direction of the qi-th parenthesis is flipped.

Output

For each event qi

, output the position of the leftmost parenthesis you need to flip in order to

get back to the balanced state.

Note that each input flipping event qi

is applied to the string after the previous flip qi−1 and its

fix.

Sample Input

6 3

((()))

4

3

1

Sample Output

2

2

1

Hint

题意

给你一个平衡的括号序列,然后每次询问是让一个括号掉转方向,让你找到一个最左边的,改变方向之后能够使得序列平衡的括号

强制在线(就是每次询问完之后,保持修改

题解:

把(想成1,)想成-1,平衡的显然就是前缀和为0

对于(改成)的,我们就找到最左边的)改成(就好了

对于)改成(的,我们就找到前缀和到结尾的最小值,大于等于2的第一个括号就好了

为什么呢?

因为我们维护的是前缀和,(改成)很显然是要-2的,所以我们只需要找到前缀和到结尾的最小值大于2的就好了,这样修改之后,也保持了平衡

我们用线段树+二分来解决

n(logn+logn)的和nlognlogn 的都比较好想

代码

#include<bits/stdc++.h>
using namespace std; typedef int SgTreeDataType;
struct treenode
{
int L , R ;
SgTreeDataType sum , lazy;
SgTreeDataType now;
void updata(SgTreeDataType v)
{
sum += v;
lazy += v;
}
}; treenode tree[300005*4]; void push_down(int o)
{
SgTreeDataType lazyval = tree[o].lazy;
tree[2*o].updata(lazyval) ; tree[2*o+1].updata(lazyval);
tree[o].lazy = 0;
} void push_up(int o)
{
tree[o].sum = min(tree[2*o].sum , tree[2*o+1].sum);
} void build_tree(int L , int R , int o)
{
tree[o].L = L , tree[o].R = R, tree[o].lazy = 0;
tree[o].now = 1e9;
tree[o].sum = 0;
if (R > L)
{
int mid = (L+R) >> 1;
build_tree(L,mid,o*2);
build_tree(mid+1,R,o*2+1);
}
} void updata_pre(int QL,int QR,SgTreeDataType v,int o)
{
int L = tree[o].L , R = tree[o].R;
if (QL <= L && R <= QR) tree[o].updata(v);
else
{
push_down(o);
int mid = (L+R)>>1;
if (QL <= mid) updata_pre(QL,QR,v,o*2);
if (QR > mid) updata_pre(QL,QR,v,o*2+1);
push_up(o);
}
} void updata_idx(int QL,int QR,SgTreeDataType v,int o)
{
int L = tree[o].L , R = tree[o].R;
if (QL <= L && R <= QR)tree[o].now = v;
else
{
int mid = (L+R)>>1;
if (QL <= mid) updata_idx(QL,QR,v,o*2);
if (QR > mid) updata_idx(QL,QR,v,o*2+1);
tree[o].now = min(tree[o*2].now , tree[o*2+1].now);
}
} SgTreeDataType query(int QL,int QR,int o)
{
int L = tree[o].L , R = tree[o].R;
if (QL <= L && R <= QR) return tree[o].sum;
else
{
push_down(o);
int mid = (L+R)>>1;
SgTreeDataType res = 1e9;
if (QL <= mid) res = min(res,query(QL,QR,2*o));
if (QR > mid) res = min(res,query(QL,QR,2*o+1));
push_up(o);
return res;
}
}
SgTreeDataType query2(int QL,int QR,int o)
{
int L = tree[o].L , R = tree[o].R;
if (QL <= L && R <= QR) return tree[o].now;
else
{
int mid = (L+R)>>1;
SgTreeDataType res = 1e9;
if (QL <= mid) res = min(res,query2(QL,QR,2*o));
if (QR > mid) res = min(res,query2(QL,QR,2*o+1));
return res;
}
}
char str[300005];
int sum[300005]; int main()
{
int n,q;
scanf("%d%d",&n,&q);
scanf("%s",str+1);
build_tree(1,n,1);
for(int i=1;i<=n;i++)
{
if(str[i]=='(')
{
updata_pre(i,n,1,1);
updata_idx(i,i,1,1);
}
else
{
updata_pre(i,n,-1,1);
updata_idx(i,i,-1,1);
}
} while(q--)
{
int x;
scanf("%d",&x);
if(str[x]=='(')
{
str[x]=')';
updata_idx(x,x,-1,1);
updata_pre(x,n,-2,1);
int l = 1,r = x;
while(l<=r)
{
int mid = (l+r)/2;
if(query2(1,mid,1)<0)r=mid-1;
else l=mid+1;
}
printf("%d\n",l);
updata_idx(l,l,1,1);
updata_pre(l,n,2,1);
str[l]='(';
}
else if(str[x]==')')
{
str[x]='(';
updata_idx(x,x,1,1);
updata_pre(x,n,2,1);
int l = 1,r = x;
while(l<=r)
{
int mid = (l+r)/2;
if(query(mid,x,1)>=2)r=mid-1;
else l=mid+1;
}
printf("%d\n",l);
updata_idx(l,l,-1,1);
updata_pre(l,n,-2,1);
str[l]=')';
}
//printf("%s\n",str+1);
}
}

Codeforces Gym 100803G Flipping Parentheses 线段树+二分的更多相关文章

  1. Gym 100803G Flipping Parentheses

    题目链接:http://codeforces.com/gym/100803/attachments/download/3816/20142015-acmicpc-asia-tokyo-regional ...

  2. Codeforces GYM 100114 D. Selection 线段树维护DP

    D. Selection Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100114 Descriptio ...

  3. Codeforces Gym 100733J Summer Wars 线段树,区间更新,区间求最大值,离散化,区间求并

    Summer WarsTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/contest/view.a ...

  4. CSU - 1542 Flipping Parentheses (线段树)

    CSU - 1542 Flipping Parentheses Time Limit: 5000MS   Memory Limit: 262144KB   64bit IO Format: %lld ...

  5. Codeforces Gym 100231B Intervals 线段树+二分+贪心

    Intervals 题目连接: http://codeforces.com/gym/100231/attachments Description 给你n个区间,告诉你每个区间内都有ci个数 然后你需要 ...

  6. Educational Codeforces Round 64 (Rated for Div. 2) (线段树二分)

    题目:http://codeforces.com/contest/1156/problem/E 题意:给你1-n  n个数,然后求有多少个区间[l,r] 满足    a[l]+a[r]=max([l, ...

  7. Codeforces 1500E - Subset Trick(线段树)

    Codeforces 题目传送门 & 洛谷题目传送门 一道线段树的套路题(似乎 ycx 会做这道题?orzorz!!11) 首先考虑什么样的 \(x\) 是"不合适"的,我 ...

  8. hdu4614 线段树+二分 插花

    Alice is so popular that she can receive many flowers everyday. She has N vases numbered from 0 to N ...

  9. 洛谷P4344 脑洞治疗仪 [SHOI2015] 线段树+二分答案/分块

    !!!一道巨恶心的数据结构题,做完当场爆炸:) 首先,如果你用位运算的时候不小心<<打成>>了,你就可以像我一样陷入疯狂的死循环改半个小时 然后,如果你改出来之后忘记把陷入死循 ...

随机推荐

  1. 使用Spring MVC统一异常处理实战

    1 描述 在J2EE项目的开发中,不管是对底层的数据库操作过程,还是业务层的处理过程,还是控制层的处理过程,都不可避免会遇到各种可预知的.不可预知的异常需要处理.每个过程都单独处理异常,系统的代码耦合 ...

  2. 【LeetCode】139 - Word Break

    Given a string s and a dictionary of words dict, determine if s can be segmented into a space-separa ...

  3. 事务处理: databse jdbc mybatis spring

    事务的认识需要一个相当漫长的流程,慢慢在实践中理解,然后在强化相关理论基础. 数据库中的事务: 传统的本地事务处理都是依靠数据库自身事务处理能力,而事务本身是传统关系型数据库的基石.简单来说事务就是一 ...

  4. 面经-csdn

    刚刚看的博文:http://blog.csdn.net/ns_code/article/details/40408397 里面有些资料值得学习! 写在前面 结束了在百度的实习,是时候写下校招的总结了, ...

  5. Hibernate中openSession() 与 getCurrentSession()的区别

    1 getCurrentSession创建的session会和绑定到当前线程,而openSession每次创建新的session. 2 getCurrentSession创建的线程会在事务回滚或事物提 ...

  6. Java基础 —— Java常用类

    Java常用类: java.lang包: java.lang.Object类: hashcode()方法:返回一段整型的哈希码,代表地址. toString()方法:返回父类名+"@&quo ...

  7. Spark RDD概念学习系列之RDD的依赖关系(宽依赖和窄依赖)(三)

    RDD的依赖关系?   RDD和它依赖的parent RDD(s)的关系有两种不同的类型,即窄依赖(narrow dependency)和宽依赖(wide dependency). 1)窄依赖指的是每 ...

  8. OpenGL复习要点

    [OpenGL要点复习] 1.和像素有关的信息(例如像素的颜色)组织成位平面 (bitplane)的形式,位平面又可以组织成帧缓冲区(framebuffer)的形式.位平面是一块内存区域,保存了屏幕上 ...

  9. HDU 4618 Palindrome Sub-Array (2013多校2 1008 暴力)

    Palindrome Sub-Array Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Oth ...

  10. unigui 导入导出数据

    导入:首先要用TUniFileUpload将文件从客户端上传至服务端,然后完成导入. TUniFileUpload上传文件的演示代码: UniFileUpload1.Execute; UniFileU ...