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] 线段树+二分答案/分块
!!!一道巨恶心的数据结构题,做完当场爆炸:) 首先,如果你用位运算的时候不小心<<打成>>了,你就可以像我一样陷入疯狂的死循环改半个小时 然后,如果你改出来之后忘记把陷入死循 ...
随机推荐
- 淘宝API开发(三)
自动登录到淘宝定时获取订单: C#控制台程序 第一步,获得淘宝真实登录地址.淘宝授权地址(https://oauth.taobao.com/authorize?response_type=token& ...
- Quartz使用总结
废话的前言 以前凭借年轻,凡事都靠脑记.现在工作几年后发现,很多以前看过.用过的东西,再次拿起的时候总觉得记不牢靠."好记性不如烂笔头"应该是某位上了年纪的大叔的切肤之痛(仅次于上 ...
- MATLAB 通过二进制读写文件
这几天在做信息隐藏方面的应用,在读写文本文件时耗费许久,故特别的上网学习一二,这里给出一常用读写,其他的都类似. 很多时候,我们都要将一个.txt以二进制方式读出来,操作后在恢复成.txt文本. ma ...
- 三角剖分求多边形面积的交 HDU3060
//三角剖分求多边形面积的交 HDU3060 #include <iostream> #include <cstdio> #include <cstring> #i ...
- 【原创】开发Kafka通用数据平台中间件
开发Kafka通用数据平台中间件 (含本次项目全部代码及资源) 目录: 一. Kafka概述 二. Kafka启动命令 三.我们为什么使用Kafka 四. Kafka数据平台中间件设计及代码解析 五. ...
- geeksforgeeks@ Sorting Elements of an Array by Frequency (Sort)
http://www.practice.geeksforgeeks.org/problem-page.php?pid=493 Sorting Elements of an Array by Frequ ...
- 【转】 ASP.NET网站路径中~(波浪线)解释
刚开始学习ASP.NET的朋友可能会不理解路径中的-符代表什么,例如ImageUrl=”~/Images/SampleImage.jpg” 现在我们看看-代表什么意思.-是ASP.NET 的Web 应 ...
- 【转】eclipse.ini内存设置
-vmargs -Xms128M -Xmx512M -XX:PermSize=64M -XX:MaxPermSize=128M 这里有几个问题:1. 各个参数的含义什么?2. 为什么有的机器我将-Xm ...
- JS制作的简单的三级及联
前台: <form id="form1" runat="server"> <div> 省 <select id="Pro ...
- 【Cocos2d-X开发学习笔记】第18期:动作类之改变动作对象、函数回调动作以及过程动作的使用
本系列学习教程使用的是cocos2d-x-2.1.4(最新版为3.0alpha0-pre) ,PC开发环境Windows7,C++开发环境VS2010 一.改变动作执行对象 CCTargetedAct ...