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.

N Qsq1⋮qQN Qsq1⋮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

6 3
((()))
4
3
1 20 9
()((((()))))()()()()
15
20
13
5
3
10
3
17
18

Sample Output

2
2
1
2
20
8
5
3
2
2
3
18

Hint

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 “(()())”.

这题简直爆炸,知道感觉需要用线段树维护,但是不知道查询,而且我线段树血都写不出了

好久好久没有写过线段树了,板子都不会了, 更别说应用了。

题意:就是给你一个匹配好的括号串长度为n,在给你m个操作,每个操作就给翻转摸一个位置的括号,

对于每一个操作,你要找到一括号将其翻转,使得最后这个串还是匹配的,

若存在多个解,翻转最左边的那个括号。

( 为 1,   )为-1 ,然后容易联想到前缀和,

然后就是用线段树去维护这个前缀和,

如果是  x = )  就是找到第一个 ) 这个相对简单 ,用set和线段树都可以做

如果是 x = ( 就是从左到右 找到第一个 ( 这个就只能用线段树实现了

记录了前缀和,其实只要找到一段区间的最小值都大于1就行了;

这个就是整个线段树最难的部分了,

int query1(int rt, int L, int R) {
        if (L == R) return L + 1;
        int mid = (L + R) >> 1;
        pushdown(rt);
        if (tree[rt << 1 | 1].r < 2 ) query1(rt << 1 | 1, mid + 1, R);
        else query1(rt << 1, L, mid);

}

当时的我怎么也想不出。 太菜了;

注意每一个找到了y  记得更新 y

 #include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
const int maxn = 3e5 + ;
char s[maxn];
int sum[maxn];
struct node {
int l, r, add;
} tree[maxn * ];
int fun(int i) {
return s[i] == '(' ? : -;
}
void pushup(int rt) {
tree[rt].l = min(tree[rt << | ].l, tree[rt << ].l);
tree[rt].r = min(tree[rt << | ].r, tree[rt << ].r);
}
void pushdown(int rt) {
tree[rt << ].l += tree[rt].add;
tree[rt << ].r += tree[rt].add;
tree[rt << ].add += tree[rt].add;
tree[rt << | ].l += tree[rt].add;
tree[rt << | ].r += tree[rt].add;
tree[rt << | ].add += tree[rt].add;
tree[rt].add = ;
}
void build(int rt, int L, int R) {
tree[rt].add = ;
if (L == R) {
tree[rt].l = sum[L] - L;
tree[rt].r = sum[L];
return ;
}
int mid = (L + R) >> ;
build(rt << , L, mid);
build(rt << | , mid + , R );
pushup(rt);
}
void updata(int rt, int L, int R, int x, int add) {
if (x <= L) {
tree[rt].add += add;
tree[rt].l += add;
tree[rt].r += add;
return ;
}
pushdown(rt);
int mid = (L + R) >> ;
if (x <= mid) updata(rt << , L, mid, x, add);
updata(rt << | , mid + , R, x, add);
pushup(rt);
}
int query1(int rt, int L, int R) {
if (L == R) return L + ;
int mid = (L + R) >> ;
pushdown(rt);
if (tree[rt << | ].r < ) query1(rt << | , mid + , R);
else query1(rt << , L, mid);
}
int query2(int rt, int L, int R) {
if (L == R ) return L;
int mid = (L + R) / ;
pushdown(rt);
if (tree[rt << ].l < ) query2(rt << , L, mid);
else query2((rt << ) + , mid + , R) ;
} int main() {
int n, q, len, x, y;
while(scanf("%d%d", &n, &q) != EOF) {
s[] = '';
memset(sum, , sizeof(sum));
scanf("%s", s + );
len = strlen(s) - ;
for (int i = ; i <= len ; i++)
sum[i] = sum[i - ] + fun(i);
build(, , len);
for (int i = ; i <= q ; i++) {
scanf("%d", &x);
s[x] = (s[x] == '(' ? ')' : '('); if (s[x] == ')') updata(, , len, x, -);
else updata(, , len, x, ); if (s[x] == ')') y = query2(, , len);
else y = query1(, , len);
s[y] = (s[y] == '(' ? ')' : '(' );
if (s[y]=='(') updata(,,len,y,);
else updata(,,len,y,-);
printf("%d\n", y); } }
return ;
}

Flipping Parentheses~Gym 100803G的更多相关文章

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

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

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

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

  3. CSUOJ 1542 Flipping Parentheses

    ACM International Collegiate Programming Contest Asia Regional Contest, Tokyo, 2014–10–19 Problem G ...

  4. Gym 100803G Flipping Parentheses

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

  5. Flipping Parentheses(CSU1542 线段树)

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

  6. 2017 United Kingdom and Ireland Programming(Gym - 101606)

    题目很水.睡过了迟到了一个小时,到达战场一看,俩队友AC五个了.. 就只贴我补的几个吧. B - Breaking Biscuits Gym - 101606B 旋转卡壳模板题.然后敲错了. 代码是另 ...

  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. Gym 101606F - Flipping Coins - [概率DP]

    题目链接:https://codeforc.es/gym/101606/problem/F 题解: 假设 $f[i][j]$ 表示抛 $i$ 次硬币,有 $j$ 个硬币正面朝上的概率. 所以只有两种挑 ...

  9. Codeforces Gym 100610 Problem A. Alien Communication Masterclass 构造

    Problem A. Alien Communication Masterclass Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codefo ...

随机推荐

  1. Android 官方命令深入分析之android

    作者:宋志辉 android命令是一个非常重要的开发工具,它可以: 创建.删除和查看Android Virtual Devices(AVDs). 创建和更新android项目. 更新你的android ...

  2. Java 8新特性探究(三)泛型的目标类型推断

    简单理解泛型 泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数.通俗点将就是"类型的变量".这种类型变量可以用在类.接口和方法 ...

  3. Android开发技巧——TextView加载HTML的图片及代码显示问题

    前几天在做一个Gradle用户指南的应用程序,使用的是TextView来加载HTML内容(至于为什么不用WebView,我也没有认真使用并比较过,也许以后会换吧),其中遇见了一些纠结的问题,所幸主要的 ...

  4. 前端框架Bootstrap - 快速搭建网站

    Bootstrap简介         Bootstrap是Twitter推出的一个开源的用于前端开发的工具包.是一个CSS/HTML/JavaScript框架.Bootstrap是基于HTML5和C ...

  5. Java实现简易的文件的迁移器

    Java作为世界上最受欢迎的一门编程语言,自然是有原因的.比如说我们可以直接的方便的调用其中的函数来实现我们想要的功能. 一个偶然的机会,我浏览API文档时发现了一个名为FileDialog的类,然后 ...

  6. Android进程通信之一:两种序列化方式

    2月下旬辞职了,去海南度假到现在,领略了一把三亚风情也算任性和 然而这样任性带来的后果就是..不行了我必须吐槽一句.. 没毕业的找工作就这么难嘛!投了57家一家面试机会都没有,好歹给个面试机会啊!!本 ...

  7. 【一天一道LeetCode】#58. Length of Last Word

    一天一道LeetCode系列 (一)题目 Given a string s consists of upper/lower-case alphabets and empty space charact ...

  8. HashMap与HashTable面试宝典

    u012233832的专栏 初生牛犊 目录视图 摘要视图 订阅 写博客,送money.送书.送C币啦   7-8月博乐推荐文章    砸BUG 得大奖 100%中奖率   微信开发学习路线高级篇上线  ...

  9. 【算法导论】最小生成树之Prime法

    关于最小生成树的概念,在前一篇文章中已经讲到,就不在赘述了.下面介绍Prime算法:         其基本思想为:从一个顶点出发,选择由该顶点出发的最小权值边,并将该边的另一个顶点包含进来,然后找出 ...

  10. Android安全机制浅谈-android学习之旅(80)

    由于Android安全机制存在,使得漏洞利用有一些困难. ASLR:即地址空间格局随机化.ASLR使得加载程序时不使用固定的基址加载,防止攻击者直接定位攻击代码位置,从而阻止溢出攻击 NX:(No e ...