ACM International Collegiate Programming Contest

Asia Regional Contest, Tokyo, 2014–10–19

Problem G

Flipping Parentheses

Input: Standard Input

Time Limit: 5 seconds

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.

N Q s

q1

...

qQ

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 1 Sample Output 1

6 3

((()))

4

3

1

2

2

1

Sample Input 2 Sample Output 2

20 9

()((((()))))()()()()

15

20

13

5

3

10

3

17

18

2

20

8

5

3

2

2

3

18

In the first sample, the initial state is “((()))”. The 4th parenthesis is flipped and the string becomes “(((())”. Then, to keep the balance you should flip the 2nd parenthesis and get “()(())”. The next flip of the 3rd parenthesis is applied to the last state and yields “())())”. To rebalance it, you have to change the 2nd parenthesis again yielding “(()())”.

解题:利用线段树进行维护

利用前缀和 比如(())那么前缀和分别就是1、2、1、0。观察到,平衡时前缀和都是不小于0的。

现在进行反转,将一个(翻转成)会使得从当前位置开始的前缀和都减-2,为毛是减2呢?因为(这个算1,)这是算-1的,从1到-1就是2。为了维护前缀和,所以从翻转位置开始所有的后缀和都要减2。那么我们如何使得这堆括号再次平衡呢?因为是减了2,所以要找个位置,把此位置的括号翻转,能够使得后面的前缀和+2,以此来保证各前缀和都不小于0,达到平衡。做法就是从左往右,找到第一个右括号,使其翻转。

如果将)翻转成(怎么办呢?同理,此位置开始以后的所有前缀和都要+2,这样全部和又不为0了,那怎么办啊?平衡状态,所有括号方向值的和是为0的。现在是大于0,我们要减回去,当然是找一个(括号,翻转成)。那么找哪个(呢?由于要减回去,还使得各前缀和不能出现负的,所以必须找一段这样的,从最后的前缀和往前走,都得不小于2,以此保证减2后不会为负,这样连续的一段,最前面的位置,就是我们要找的那个(。然后。。。哼哼。。。。

可是可是怎么这样一段连续的不小于2的区间呢?

我们只要维护该区间的最小值即可,只要最小值不小于2,那么该区间的所有值都不会小于2。。。

这样从右往左找,搜线段树。。。

具体做法参考代码。。。

 #include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = ;
struct node {
int lt,rt,theFirst,theMin,lazy,dir;
} tree[maxn<<];
int sum,n,m;
char str[maxn];
void build(int lt,int rt,int v) {
tree[v].lt = lt;
tree[v].rt = rt;
tree[v].lazy = ;
if(lt == rt) {
tree[v].dir = str[lt] == '('?:-;
sum += tree[v].dir;
tree[v].theMin = sum;
tree[v].theFirst = tree[v].dir == ?INF:lt;
return;
}
int mid = (lt + rt)>>;
build(lt,mid,v<<);
build(mid+,rt,v<<|);
tree[v].theFirst = min(tree[v<<].theFirst,tree[v<<|].theFirst);
tree[v].theMin = min(tree[v<<].theMin,tree[v<<|].theMin);
}
int update(int p,int v) {
if(tree[v].lt >= p && tree[v].rt <= p) {
int tmp = tree[v].dir;
tree[v].dir *= -;
tree[v].theFirst = tmp == ?p:INF;
return tmp;
}
int mid = (tree[v].lt + tree[v].rt)>>,ret;
if(p <= mid) ret = update(p,v<<);
if(p > mid) ret = update(p,v<<|);
tree[v].theFirst = min(tree[v<<].theFirst,tree[v<<|].theFirst);
return ret;
}
void pushdown(int v) {
if(tree[v].lazy) {
tree[v<<].lazy += tree[v].lazy;
tree[v<<|].lazy += tree[v].lazy;
tree[v].lazy = ;
}
}
void pushup(int v) {
tree[v].theMin = min(tree[v<<].theMin+tree[v<<].lazy,tree[v<<|].theMin+tree[v<<|].lazy);
}
void update(int lt,int rt,int v,int value) {
if(tree[v].lt >= lt && tree[v].rt <= rt) {
tree[v].lazy += value;
return;
}
pushdown(v);
int mid = (tree[v].lt + tree[v].rt)>>;
if(lt <= mid) update(lt,rt,v<<,value);
if(rt > mid) update(lt,rt,v<<|,value);
pushup(v);
}
int query(int v,int o) {
if(tree[v].theMin+tree[v].lazy >= ) return tree[v].lt;
if(tree[v].lt == tree[v].rt) return o;
pushdown(v);
int ret;
if(tree[v<<|].theMin+tree[v<<|].lazy >= )
ret = query(v<<,tree[v<<|].lt);
else ret = query(v<<|,o);
pushup(v);
return ret;
}
int main() {
int p;
while(~scanf("%d %d",&n,&m)) {
scanf("%s",str+);
sum = ;
build(,n,);
while(m--) {
scanf("%d",&p);
int tmp = update(p,);
update(p,n,,tmp*-);
printf("%d\n",p = tmp == ?tree[].theFirst:query(,n));
update(p,);
update(p,n,,tmp*);
}
}
return ;
}

CSUOJ 1542 Flipping Parentheses的更多相关文章

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

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

  2. Codeforces Gym 100803G Flipping Parentheses 线段树+二分

    Flipping Parentheses 题目连接: http://codeforces.com/gym/100803/attachments Description A string consist ...

  3. Flipping Parentheses~Gym 100803G

    Description A string consisting only of parentheses '(' and ')' is called balanced if it is one of t ...

  4. Flipping Parentheses(CSU1542 线段树)

    http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1542 赛后发现这套题是2014东京区域赛的题目,看了排名才发现自己有多low  = =! 题目大意 ...

  5. CSUOJ 1542 线段树解决括号反向问题

    题目大意: 根据初始给定的合法的小括号排序,每次进行一个操作,将第a位的括号反向,找到一个尽可能靠前的括号反向后是整个括号排列合法 数据量十分大,不断进行查询,要用线段树进行logn的复杂度的查询 首 ...

  6. Gym 100803G Flipping Parentheses

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

  7. 2014-2015 ACM-ICPC, Asia Tokyo Regional Contest

    2014-2015 ACM-ICPC, Asia Tokyo Regional Contest A B C D E F G H I J K O O O O   O O         A - Bit ...

  8. [LeetCode] Remove Invalid Parentheses 移除非法括号

    Remove the minimum number of invalid parentheses in order to make the input string valid. Return all ...

  9. [LeetCode] Different Ways to Add Parentheses 添加括号的不同方式

    Given a string of numbers and operators, return all possible results from computing all the differen ...

随机推荐

  1. SharePoint Search之(七)Search result- 结果源

    在使用搜索引擎的时候.非常多情况下,用户希望限定一下搜索范围,以便更加easy找到想要的结果. watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvU1BGYXJ ...

  2. nios DMA使用注意事项

    1.对同一个设备的多次DMA读写操作之间如果并行,有可能会导致数据传输错误.可以在程序中对每次DMA操作进行等待.如下: 点击(此处)折叠或打开 void dma_done(void *p) { in ...

  3. Import Example Dataset

    Overview The examples in this guide use the restaurants collection in the test database. The followi ...

  4. zzulioj--1832--贪吃的松鼠(位运算好题)

    1832: 贪吃的松鼠 Time Limit: 3 Sec  Memory Limit: 2 MB Submit: 43  Solved: 7 SubmitStatusWeb Board Descri ...

  5. git ---- 产生冲突的场景 和解决办法

    1.git冲突的场景 情景一:多个分支代码合并到一个分支时: 情景二:多个分支向同一个远端分支推送代码时: 实际上,push操作即是将本地代码merge到远端库分支上. 关于push和pull其实就分 ...

  6. 性能测试URL自动转码

    最近做性能测试,写了个python程序自动将URL里面的‘%2B’,‘20%’,‘3B'等转换成正常字符,方便查看. import os,sys; path = sys.path[0] os.chdi ...

  7. 上传golang 版本SDK

    在上传的时候,文件都上传成功了,但是返回的信息里面errcode 404 token 是"".是不是因为我的callbackUrl(随便写的) 写错导致的. 上传golang 版本 ...

  8. [洛谷P1726][codevs1332]上白泽慧音

    题目大意:求一个有向图的最大强连通分量中点的个数,并输出这些点(字典序最小). 解题思路:裸的强连通分量. 数据小,求完强连通分量后排序+vector大小比较即可(vector有小于运算符). C++ ...

  9. TCP学习前的准备——可靠数据传输协议

    由于传输层所依赖的网络层是不可靠的,通过逐渐考虑实际情况不断引入新技术来实现可靠数据传输. 完全可信的信道 有比特差错的信道 新的协议功能: 1.    差错检测:检验和 2.    接收方反馈:序号 ...

  10. 洛谷 P2014 选课 && caioj 1108 树形动态规划(TreeDP)3:选课

    这里的先后关系可以看成节点和父亲的关系 在树里面,没有父亲肯定就没有节点 所以我们可以先修的看作父亲,后修的看作节点 所以这是一颗树 这题和上一道题比较相似 都是求树上最大点权和问题 但这道题是多叉树 ...