题目链接:http://codeforces.com/gym/100803/attachments/download/3816/20142015-acmicpc-asia-tokyo-regional-contest-en.pdf

题意:给你一些匹配好的括号,长为n,有m个操作,每次操作把其中一个"("改为")",或者把其中一个")"改为"(",问你改动一个单括号,使得改后的括号序列任然完美匹配,如果有多种该法,求出最前面的。

思路:可以分两种情况分类讨论,先求出所有下标的前缀和,如果是第一种情况,那么只要从左到右找到第一个")"就行了,可以用set维护,如果是第二种情况,那么可以用线段树维护区间的最小值,然后用二分查找出最前面的一个大于等于2,且后面的前缀和的值都大于等于2的下标。

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
#define maxn 300030
char s[maxn];
int sum[maxn];
#define inf 888888888
struct node{
int l,r,minx,add;
}b[4*maxn]; set<int>myset;
set<int>::iterator it; void build(int l,int r,int i)
{
int mid;
b[i].l=l;b[i].r=r;b[i].add=0;
if(l==r){
b[i].minx=sum[l];
return;
}
mid=(l+r)/2;
build(l,mid,i*2);
build(mid+1,r,i*2+1);
b[i].minx=min(b[i*2].minx,b[i*2+1].minx);
} void update(int l,int r,int add,int i)
{
int mid;
if(b[i].l==l && b[i].r==r){
b[i].add+=add;
b[i].minx+=add;
return;
}
if(b[i].add){
b[i*2].add+=b[i].add;
b[i*2].minx+=b[i].add;
b[i*2+1].add+=b[i].add;
b[i*2+1].minx+=b[i].add;
b[i].add=0;
}
mid=(b[i].l+b[i].r)/2;
if(r<=mid)update(l,r,add,i*2);
else if(l>mid)update(l,r,add,i*2+1);
else {
update(l,mid,add,i*2);
update(mid+1,r,add,i*2+1); }
b[i].minx=min(b[i*2].minx,b[i*2+1].minx); } int question(int l,int r,int i)
{
int mid;
if(b[i].l==l && b[i].r==r){
return b[i].minx;
}
if(b[i].add){
b[i*2].add+=b[i].add;
b[i*2].minx+=b[i].add;
b[i*2+1].add+=b[i].add;
b[i*2+1].minx+=b[i].add;
b[i].add=0;
}
mid=(b[i].l+b[i].r)/2;
if(r<=mid)return question(l,r,i*2);
else if(l>mid)return question(l,r,i*2+1);
else {
return min(question(l,mid,i*2),question(mid+1,r,i*2+1) ); }
b[i].minx=min(b[i*2].minx,b[i*2+1].minx); } int main()
{
int n,m,i,j,c,l,r,mid;
while(scanf("%d%d",&n,&m)!=EOF)
{
scanf("%s",s+1);
sum[0]=0;
myset.clear();
for(i=1;i<=n;i++){
if(s[i]=='('){
sum[i]=sum[i-1]+1;
}
else{
sum[i]=sum[i-1]-1;
myset.insert(i);
}
}
build(1,n,1);
for(i=1;i<=m;i++){
scanf("%d",&c);
if(s[c]=='('){
s[c]=')';
myset.insert(c);
update(c,n,-2,1);
it=myset.begin();
cout<<*it<<endl;
myset.erase(it);
update(*it,n,2,1);
s[*it]='(';
}
else if(s[c]==')'){
s[c]='(';
myset.erase(c);
update(c,n,2,1);
l=1;r=n;
while(l<=r){
mid=(l+r)/2;
if(question(mid,n,1)>=2)r=mid-1;
else l=mid+1;
}
printf("%d\n",l);
s[l]=')';
update(l,n,-2,1);
myset.insert(l);
}
}
}
return 0;
}

最新文章

  1. 12、产品经理要阅读的书籍 - IT软件人员书籍系列文章
  2. Python之路第一课Day9--随堂笔记之二(进程、线程、协程篇)
  3. JavaScript资源大全中文版(Awesome最新版--转载自张果老师博客)
  4. Python的闭包
  5. AStar算法的学习
  6. 【C语言入门教程】3.4 循环控制语句
  7. SQL脚本循环修改数据库字段类型
  8. ajax form表单回显
  9. hdu 3836 Equivalent Sets
  10. 【python自动化第八篇:网络编程】
  11. [转贴]Linq之动态查询
  12. CDN概念+作用+特点+原理
  13. ERROR: unable to bind listening socket for address ’127
  14. Solr6.5.0配置solrcore图文详解
  15. Beta第三天
  16. 项目Alpha冲刺Day9
  17. 一个简单文本分类任务-EM算法-R语言
  18. MAC下安装多版本JDK和切换几种方式
  19. sh脚本循环
  20. 无旋treap的简单思想以及模板

热门文章

  1. python学习笔记 | wordcloud安装指南
  2. appium元素识别方式实战
  3. React &amp; Vue2 Butterfly图编排——让数据更自由地驱动DAG
  4. LRU(Least Recently Used)最近未使用置换算法--c实现
  5. k8s用kubectl管理应用升级,服务发布与回滚,扩缩容
  6. MySQL索引性能分析
  7. Dubbo中的统一契约是如何实现的?
  8. IP2188中文资料书
  9. RecyclerView 源码分析(二) —— 缓存机制
  10. iDRAC RAC0218 最大会话数