Codeforces Gym 100803G Flipping Parentheses 线段树+二分
Flipping Parentheses
题目连接:
http://codeforces.com/gym/100803/attachments
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
Sample Output
2
2
1
Hint
题意
给你一个平衡的括号序列,然后每次询问是让一个括号掉转方向,让你找到一个最左边的,改变方向之后能够使得序列平衡的括号
强制在线(就是每次询问完之后,保持修改
题解:
把(想成1,)想成-1,平衡的显然就是前缀和为0
对于(改成)的,我们就找到最左边的)改成(就好了
对于)改成(的,我们就找到前缀和到结尾的最小值,大于等于2的第一个括号就好了
为什么呢?
因为我们维护的是前缀和,(改成)很显然是要-2的,所以我们只需要找到前缀和到结尾的最小值大于2的就好了,这样修改之后,也保持了平衡
我们用线段树+二分来解决
n(logn+logn)的和nlognlogn 的都比较好想
代码
#include<bits/stdc++.h>
using namespace std;
typedef int SgTreeDataType;
struct treenode
{
int L , R ;
SgTreeDataType sum , lazy;
SgTreeDataType now;
void updata(SgTreeDataType v)
{
sum += v;
lazy += v;
}
};
treenode tree[300005*4];
void push_down(int o)
{
SgTreeDataType lazyval = tree[o].lazy;
tree[2*o].updata(lazyval) ; tree[2*o+1].updata(lazyval);
tree[o].lazy = 0;
}
void push_up(int o)
{
tree[o].sum = min(tree[2*o].sum , tree[2*o+1].sum);
}
void build_tree(int L , int R , int o)
{
tree[o].L = L , tree[o].R = R, tree[o].lazy = 0;
tree[o].now = 1e9;
tree[o].sum = 0;
if (R > L)
{
int mid = (L+R) >> 1;
build_tree(L,mid,o*2);
build_tree(mid+1,R,o*2+1);
}
}
void updata_pre(int QL,int QR,SgTreeDataType v,int o)
{
int L = tree[o].L , R = tree[o].R;
if (QL <= L && R <= QR) tree[o].updata(v);
else
{
push_down(o);
int mid = (L+R)>>1;
if (QL <= mid) updata_pre(QL,QR,v,o*2);
if (QR > mid) updata_pre(QL,QR,v,o*2+1);
push_up(o);
}
}
void updata_idx(int QL,int QR,SgTreeDataType v,int o)
{
int L = tree[o].L , R = tree[o].R;
if (QL <= L && R <= QR)tree[o].now = v;
else
{
int mid = (L+R)>>1;
if (QL <= mid) updata_idx(QL,QR,v,o*2);
if (QR > mid) updata_idx(QL,QR,v,o*2+1);
tree[o].now = min(tree[o*2].now , tree[o*2+1].now);
}
}
SgTreeDataType query(int QL,int QR,int o)
{
int L = tree[o].L , R = tree[o].R;
if (QL <= L && R <= QR) return tree[o].sum;
else
{
push_down(o);
int mid = (L+R)>>1;
SgTreeDataType res = 1e9;
if (QL <= mid) res = min(res,query(QL,QR,2*o));
if (QR > mid) res = min(res,query(QL,QR,2*o+1));
push_up(o);
return res;
}
}
SgTreeDataType query2(int QL,int QR,int o)
{
int L = tree[o].L , R = tree[o].R;
if (QL <= L && R <= QR) return tree[o].now;
else
{
int mid = (L+R)>>1;
SgTreeDataType res = 1e9;
if (QL <= mid) res = min(res,query2(QL,QR,2*o));
if (QR > mid) res = min(res,query2(QL,QR,2*o+1));
return res;
}
}
char str[300005];
int sum[300005];
int main()
{
int n,q;
scanf("%d%d",&n,&q);
scanf("%s",str+1);
build_tree(1,n,1);
for(int i=1;i<=n;i++)
{
if(str[i]=='(')
{
updata_pre(i,n,1,1);
updata_idx(i,i,1,1);
}
else
{
updata_pre(i,n,-1,1);
updata_idx(i,i,-1,1);
}
}
while(q--)
{
int x;
scanf("%d",&x);
if(str[x]=='(')
{
str[x]=')';
updata_idx(x,x,-1,1);
updata_pre(x,n,-2,1);
int l = 1,r = x;
while(l<=r)
{
int mid = (l+r)/2;
if(query2(1,mid,1)<0)r=mid-1;
else l=mid+1;
}
printf("%d\n",l);
updata_idx(l,l,1,1);
updata_pre(l,n,2,1);
str[l]='(';
}
else if(str[x]==')')
{
str[x]='(';
updata_idx(x,x,1,1);
updata_pre(x,n,2,1);
int l = 1,r = x;
while(l<=r)
{
int mid = (l+r)/2;
if(query(mid,x,1)>=2)r=mid-1;
else l=mid+1;
}
printf("%d\n",l);
updata_idx(l,l,-1,1);
updata_pre(l,n,-2,1);
str[l]=')';
}
//printf("%s\n",str+1);
}
}
Codeforces Gym 100803G Flipping Parentheses 线段树+二分的更多相关文章
- Gym 100803G Flipping Parentheses
题目链接:http://codeforces.com/gym/100803/attachments/download/3816/20142015-acmicpc-asia-tokyo-regional ...
- Codeforces GYM 100114 D. Selection 线段树维护DP
D. Selection Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100114 Descriptio ...
- Codeforces Gym 100733J Summer Wars 线段树,区间更新,区间求最大值,离散化,区间求并
Summer WarsTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/contest/view.a ...
- CSU - 1542 Flipping Parentheses (线段树)
CSU - 1542 Flipping Parentheses Time Limit: 5000MS Memory Limit: 262144KB 64bit IO Format: %lld ...
- Codeforces Gym 100231B Intervals 线段树+二分+贪心
Intervals 题目连接: http://codeforces.com/gym/100231/attachments Description 给你n个区间,告诉你每个区间内都有ci个数 然后你需要 ...
- Educational Codeforces Round 64 (Rated for Div. 2) (线段树二分)
题目:http://codeforces.com/contest/1156/problem/E 题意:给你1-n n个数,然后求有多少个区间[l,r] 满足 a[l]+a[r]=max([l, ...
- Codeforces 1500E - Subset Trick(线段树)
Codeforces 题目传送门 & 洛谷题目传送门 一道线段树的套路题(似乎 ycx 会做这道题?orzorz!!11) 首先考虑什么样的 \(x\) 是"不合适"的,我 ...
- hdu4614 线段树+二分 插花
Alice is so popular that she can receive many flowers everyday. She has N vases numbered from 0 to N ...
- 洛谷P4344 脑洞治疗仪 [SHOI2015] 线段树+二分答案/分块
!!!一道巨恶心的数据结构题,做完当场爆炸:) 首先,如果你用位运算的时候不小心<<打成>>了,你就可以像我一样陷入疯狂的死循环改半个小时 然后,如果你改出来之后忘记把陷入死循 ...
随机推荐
- struct 与 typedef struct
1. 基本解释 typedef为C语言的关键字,作用是为一种数据类型定义一个新名字.这里的数据类型包括内部数据类型(int,char等)和自定义的数据类型(struct等). 在编程中使用typede ...
- bjfu1281
思路挺简单的,但因为需要处理大数,所以就比较耗代码了. /* * Author : ben */ #include <cstdio> #include <cstdlib> #i ...
- MySQL_PHP学习笔记_2015_0923_MySQL如何开启事件
1. 查看事件状态>>>>>>>>>>>>>>>>>>>>>>> ...
- 150个JS特效脚本
收集了其它一些不太方便归类的JS特效,共150个,供君查阅. 1. simplyScroll simplyScroll这个jQuery插件能够让任意一组元素产生滚动动画效果,可以是自动.手动滚动,水平 ...
- java开发eclipse常见问题(一)The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path
最近刚开始用Eclipse开发,刚开始都是按教程一步一步的新建web工程也没出现什么问题. 今天选了一个新的workspace,建了个web工程发现最简单的jsp页面都报错:The superclas ...
- [转]Javascript定义类的三种方法
作者: 阮一峰 原文地址:http://www.ruanyifeng.com/blog/2012/07/three_ways_to_define_a_javascript_class.html 将近2 ...
- ACM2050前传
n在一个平面上有一个圆和n条直线,这些直线中每一条在圆内 同其他直线相交,假设没有3条直线相交于一点,试问这些直线 将圆分成多少区域. 使用递归 F(1)=2; F(n) = F(n-1)+n; ...
- ASP.NET MVC - 发布网站
原文地址:http://www.w3school.com.cn/aspnet/mvc_publish.asp 学习如何在不使用 Visual Web Developer 的情况下发布 MVC 应用程序 ...
- 数据库 CHECKDB 发现了x个分配错误和 x 个一致性错误
--1.在SQL查询分析器中执行以下语句:(注以下所用的POS为数据库名称,请用户手工改为自己的数据库名) use pos dbcc checkdb --2.查看查询结果,有很多红色字体显示,最后结果 ...
- Home vs2013
Microsoft Visual Studio Ultimate 2013 版本 12.0.30110.00 Update 1 Microsoft .NET Framework 版本 4.5. ...