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 ...
随机推荐
- pig的udf编写
http://www.cnblogs.com/anny-1980/p/3673569.html http://blog.csdn.net/ruishenh/article/details/120480 ...
- Gradle笔记——依赖管理基础
1. 什么是依赖管理 依赖管理可以分为两部分:一是依赖,即项目构建或运行时所需要的一些文件:二是发布,即构建完成后上传到某个地方. 1.1 依赖 大部分的项目都需要第三方库类或项目文件,这些文件就是项 ...
- UNIX环境高级编程——标准I/O库函数和Unbuffered I/O函数
以写文件为例,C标准I/O库函数(printf(3) .putchar(3) .fputs(3) )与系统调用write(2) 的关 系如下图所示. 库函数与系统调用的层次关系 open .read ...
- FSG报表打印报错,log文件显示java.sql.SQLException: No corresponding LOB data found
报错信息: +---------------------------------------------------------------------------+ Plsql 程序的日志信息开始 ...
- ValueError: setting an array element with a sequence.
http://blog.csdn.net/pipisorry/article/details/48031035 From the code you showed us, the only thing ...
- 《java入门第一季》之面向对象匿名内部类面试题
面试题一: /* 按照要求,补齐代码 interface Inter { void show(); } class Outer { // ...
- uGUI使用代码动态添加Button.OnClick()事件(Unity3D开发之十二)
猴子原创,欢迎转载.转载请注明: 转载自Cocos2Der-CSDN,谢谢! 原文地址: http://blog.csdn.net/cocos2der/article/details/42705885 ...
- Java-Iterator总结
纸上得来终觉浅,绝知此事要躬行 --陆游 问渠那得清如许,为有源头活水来 --朱熹 迭 代器是一种设计模式,它是一个对象,它可以遍历并选择序列中的对象,而开发人员不需要了解该序列的底层结构. ...
- Linux 打开句柄限制的调整
Linux 打开句柄限制的调整 参考文章: Linux---进程句柄限制总结(http://blog.csdn.net/jhcsdb/article/details/32338953) !! 本文内容 ...
- Bootstrap 简介: 创建响应式、移动项目的工具
原文链接: Introduction to Bootstrap: A Tool for Building Responsive, Mobile-First Projects 下载: 示例代码Boots ...