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] 线段树+二分答案/分块
!!!一道巨恶心的数据结构题,做完当场爆炸:) 首先,如果你用位运算的时候不小心<<打成>>了,你就可以像我一样陷入疯狂的死循环改半个小时 然后,如果你改出来之后忘记把陷入死循 ...
随机推荐
- struts2中错误处理
定义一个 package,然后其他package都继承 这个package struts-global 就 有了这个错误处理功能了 然后再自己写个类 struts.xml <constant n ...
- n个数的最小公倍数
Description 求n个数的最小公倍数. Input 输入包含多个测试实例,每个测试实例的开始是一个正整数n,然后是n个正整数. Output 为每组测试数据输出它们的最小公倍数,每个测 ...
- ansible命令执行模块使用
ansible命令执行模块使用 1.命令执行模块-command 在远程节点上运行命令. 命令模块使用命令名称,接上空格-的分割符作为参数使用,但是不支持管道符和变量等,如果要使用这些,那么可以使用s ...
- C#入门基础
那么由 = 连接起来的这个式子 就叫赋值表达式 解决异常的 办法 for循环 常量 常量在程序中 怎么定义: const 类型 常量名= 值; 在程序中可以改变常量的值吗 不可以 一旦改变 ...
- VBA
1.ActiveWorkbook是Application对象的一个属性,表示的是一个active Workbook. 2.Application对象可以获得一些顶级的对象,比如ActiveCell,A ...
- Java基础 —— Java常用类
Java常用类: java.lang包: java.lang.Object类: hashcode()方法:返回一段整型的哈希码,代表地址. toString()方法:返回父类名+"@&quo ...
- HDU ACM 1051/ POJ 1065 Wooden Sticks
Wooden Sticks Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tot ...
- Options for Debugging Your Program or GCC
[Options for Debugging Your Program or GCC] -g Produce debugging information in the operating system ...
- UVALive 7079 - How Many Maos Does the Guanxi Worth(最短路Floyd)
https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_probl ...
- 深入理解inode与软硬链接
一.inode是什么? 理解inode,要从文件储存说起. 文件储存在硬盘上,硬盘的最小存储单位叫做"扇区"(Sector).每个扇区储存512字节(相当于0.5KB). 操作系统 ...