Flipping Parentheses~Gym 100803G
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 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的更多相关文章
- Codeforces Gym 100803G Flipping Parentheses 线段树+二分
Flipping Parentheses 题目连接: http://codeforces.com/gym/100803/attachments Description A string consist ...
- CSU - 1542 Flipping Parentheses (线段树)
CSU - 1542 Flipping Parentheses Time Limit: 5000MS Memory Limit: 262144KB 64bit IO Format: %lld ...
- CSUOJ 1542 Flipping Parentheses
ACM International Collegiate Programming Contest Asia Regional Contest, Tokyo, 2014–10–19 Problem G ...
- Gym 100803G Flipping Parentheses
题目链接:http://codeforces.com/gym/100803/attachments/download/3816/20142015-acmicpc-asia-tokyo-regional ...
- Flipping Parentheses(CSU1542 线段树)
http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1542 赛后发现这套题是2014东京区域赛的题目,看了排名才发现自己有多low = =! 题目大意 ...
- 2017 United Kingdom and Ireland Programming(Gym - 101606)
题目很水.睡过了迟到了一个小时,到达战场一看,俩队友AC五个了.. 就只贴我补的几个吧. B - Breaking Biscuits Gym - 101606B 旋转卡壳模板题.然后敲错了. 代码是另 ...
- 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 ...
- Gym 101606F - Flipping Coins - [概率DP]
题目链接:https://codeforc.es/gym/101606/problem/F 题解: 假设 $f[i][j]$ 表示抛 $i$ 次硬币,有 $j$ 个硬币正面朝上的概率. 所以只有两种挑 ...
- Codeforces Gym 100610 Problem A. Alien Communication Masterclass 构造
Problem A. Alien Communication Masterclass Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codefo ...
随机推荐
- Android光线传感器-android学习之旅(65)
主要讲解光线传感器的使用,其实所有的传感器用法类似 主要是定义一个TextView用来显示光线强度,用完了以后记得在OnDestory里面释放资源 代码如下 public class MainActi ...
- Chapter 2 User Authentication, Authorization, and Security(6):服务器权限授予粒度
原文出处:http://blog.csdn.net/dba_huangzj/article/details/38867489,专题目录:http://blog.csdn.net/dba_huangzj ...
- 谈谈Ext JS的组件——容器与布局
概述 在页面中,比较棘手的地方就是布局.而要实现布局,就得有能维护布局的容器.可以说,在我试过和使用过的Javascript框架中,Ext JS的布局是做得最棒的一个,而这得益于它强大的容器类和丰富的 ...
- 【leetcode77】Single Number
一题目描述: 给定一个数组,只有一个数字出现一次,其余都是两次,判断那个数字 思路: 不断取出数据进行异或,最后一个数字,因为相同的数字会抵消 代码: public class Solution { ...
- python的IndentationError: unexpected indent python
都知道python是对格式要求很严格的,写了一些python但是也没发现他严格在哪里,今天遇到了IndentationError: unexpected indent错误我才知道他是多么的严格. ...
- 深入理解 JSX
JSX 是一个看起来很像 XML 的 JavaScript 语法扩展.React 可以用来做简单的 JSX 句法转换. 为什么要使用 JSX? 你不需要为了 React 使用 JSX,可以直接使用纯粹 ...
- cas 单点登录(SSO)之一: jasig cas-server 安装
cas 单点登录(SSO)实验之一: jasig cas-server 安装 参考文章: http://my.oschina.net/indestiny/blog/200768#comments ht ...
- 放yy直播点赞动画
最近在做直播相关的东西,这个动画是IOS先撸出来的,后来android这边要模仿,大部分直播应用都有很炫酷的点赞动画,所以也没什么好稀奇的.如果有现成的轮子了,就没必要自己再造了,后来参照了程序亦非猿 ...
- Android中代码运行指定的Apk
有时候,当我们编写自己的应用的时候,需要通过代码实现指定的apk,安装指定的主题,或者安装新的apk.可以通过以下方法实现: private void installAPK(String apkUrl ...
- 谈谈java虚拟机
本文可作为北京圣思元深入java虚拟机的课堂笔记. 先看一个令人dan teng的面试题 public class Singleton { public static Singleton s=new ...