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 ...
随机推荐
- 联发科安卓6.0项目的到来的第一个难题:tar的分包与并包
tar 分包压缩与合并 今天是个高兴的日子,迎来了新项目----联发科平板.但是遇到了难题,tar的分包压缩与合并居然在资料书上找不 到,于是我赶紧百度,找到了相关资料. 在工程目录下遇到了大量的gz ...
- UNIX环境高级编程——进程基本概述
一.什么是进程 从用户的角度来看进程是程序的一次执行过程.从操作系统的核心来看,进程是操作系统分配的内存.CPU时间片等资源的基本单位.进程是资源分配的最小单位.每一个进程都有自己独立的地址空间与执行 ...
- leetcode 20 Valid Parentheses 括号匹配
Given a string containing just the characters '(', ')', '{', '}', '[' and']', determine if the input ...
- Let the Balloon Rise HDU 1004
Let the Balloon Rise Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other ...
- XBMC源代码分析 7:视频播放器(dvdplayer)-输入流(以libRTMP为例)
前文分析了XBMC的基本结构: XBMC源代码分析 1:整体结构以及编译方法 XBMC源代码分析 2:Addons(皮肤Skin) XBMC源代码分析 3:核心部分(core)-综述 XBMC源代码分 ...
- 程序压力测试、性能测试AB、Webbench、Tsung
负载生成器是一些生成用于测试的流量的程序.它们可以向你展示服务器在高负载的情况下的性能,以及让你能够找出服务器可能存在的问题.为了得到更加客观和准确的数值,应该从远程访问.局域网访问 ...
- Android Widget工作原理详解(一) 最全介绍
转载请标明出处:http://blog.csdn.net/sk719887916/article/details/46853033 ; Widget是安卓的一应用程序组件,学名窗口小部件,它是微型应用 ...
- FFMPEG结构体分析:AVFormatContext
注:写了一系列的结构体的分析的文章,在这里列一个列表: FFMPEG结构体分析:AVFrameFFMPEG结构体分析:AVFormatContextFFMPEG结构体分析:AVCodecContext ...
- "《算法导论》之‘图’":深度优先搜索、宽度优先搜索(无向图、有向图)
本文兼参考自<算法导论>及<算法>. 以前一直不能够理解深度优先搜索和广度优先搜索,总是很怕去碰它们,但经过阅读上边提到的两本书,豁然开朗,马上就能理解得更进一步. 下文将会用 ...
- 详解Linux2.6内核中基于platform机制的驱动模型 (经典)
[摘要]本文以Linux 2.6.25 内核为例,分析了基于platform总线的驱动模型.首先介绍了Platform总线的基本概念,接着介绍了platform device和platform dri ...