CSU 1809 Parenthesis【思维+线段树】好题~
2017-04-25 21:18
639 查看
1809: Parenthesis
Submit Page
Summary Time
Limit: 5 Sec Memory
Limit: 128 Mb Submitted: 1500 Solved: 398
Description
Bobo has a balanced parenthesis sequence P=p1 p2…pn oflength n and q questions.
The i-th question is whether P remains balanced after pai and pbi swapped.
Note that questions are individual so that they have no affect on others.
Parenthesis sequence S is balanced if and only if:
1. S is empty;
2. or there exists balanced parenthesis sequence A,B such that S=AB;
3. or there exists balanced parenthesis sequence S' such that S=(S').
Input
The input contains at most 30 sets. For each set:The first line contains two integers n,q (2≤n≤105,1≤q≤105).
The second line contains n characters p1 p2…pn.
The i-th of the last q lines contains 2 integers ai,bi (1≤ai,bi≤n,ai≠bi).
Output
For each question, output "Yes" if P remains balanced, or "No" otherwise.
Sample Input
4 2 (()) 1 3 2 3 2 1 () 1 2
Sample Output
No Yes No
Hint
Source
湖南省第十二届大学生计算机程序设计竞赛题目大意:
给你一个长度为N的括号匹配串,然后有q个查询,表示交换两个位子上的括号之后,询问你字符串还是否构成括号匹配。
思路:
首先预处理出一个前缀和sum【i】,设定(表示1,)表示-1.那么我们开始分类讨论:
①a【x】==a【y】,那么结果一定是Yes.
②a【x】==‘)’&&a【y】==‘(’,那么结果也一定是Yes.因为如果左边的右括号放置在了右边,可以和放置在左边的这个左括号进行匹配,原串保证是匹配的,所以这样交换的结果也一定是Yes.
③a【x】==‘(’&&a【y】==‘)’,那么考虑对前缀和的影响:
撤销x位子上的左括号:从x-------------->n 前缀和全部减去1
撤销y位子上的右括号:从y-------------->n 前缀和全部加上1
放置x位子上那个右括号:从x----------->n 前缀和全部减去1
放置y位子上那个左括号:从y----------->n 前缀和全部加上1
显然,如果有某个前缀和的位子上出现了负数,那么此时这个字符串一定是构不成括号匹配的,所以我们只要判定影响到的部分是否会出现负数即可。
显然,从y---------->n的部分都加上了2,从x---------->y-1的部分都减去了1.
那么我们只要查询之前前缀和中区间【x,y-1】中的最小值是否大于等于2即可,如果是,结果就是Yes.否则就是No.
Ac代码:
#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
#define lson l,m,rt*2
#define rson m+1,r,rt*2+1
int tree[1000050*8];
char a[405000];
int sum[405000];
void pushup(int rt)
{
tree[rt]=min(tree[rt<<1],tree[rt<<1|1]);
}
int Query(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R)
{
return tree[rt];
}
else
{
int m=(l+r)>>1;
int ans=0x3f3f3f3f;
if(L<=m)
{
ans=min(Query(L,R,lson),ans);
}
if(m<R)
{
ans=min(Query(L,R,rson),ans);
}
return ans;
}
}
void build( int l ,int r , int rt )
{
if( l == r )
{
tree[rt]=0x3f3f3f3f;
return ;
}
else
{
int m = (l+r)>>1 ;
build(lson) ;
build(rson) ;
pushup(rt) ;
}
}
void update(int p,int c,int l,int r,int rt)//p阵营c数据.
{
if(l==r)
{
tree[rt]=min(tree[rt],c);
}
else
{
int m=(l+r)>>1;
if(p<=m) update(p,c,lson);
else update(p,c,rson);
pushup(rt);
}
}
int main()
{
int n,q;
while(~scanf("%d%d",&n,&q))
{
scanf("%s",a);
sum[0]=1;
build(1,n,1);
for(int i=1;i<n;i++)
{
int tmp=0;
if(a[i]=='(')tmp=1;
else tmp=-1;
sum[i]=sum[i-1]+tmp;
}
for(int i=1;i<=n;i++)update(i,sum[i-1],1,n,1);
while(q--)
{
int x,y;
scanf("%d%d",&x,&y);
if(x>y)swap(x,y);
if(a[x-1]==a[y-1])printf("Yes\n");
if(a[x-1]==')'&&a[y-1]=='(')printf("Yes\n");
if(a[x-1]=='('&&a[y-1]==')')
{
if(Query(x,y-1,1,n,1)<2)printf("No\n");
else printf("Yes\n");
}
}
}
}
相关文章推荐
- CSU 1809 Parenthesis(RMQ||线段树)
- CSU 1809 Parenthesis(RMQ||线段树)
- CSU 1809 Parenthesis(RMQ||线段树)
- CSU 1809 Parenthesis(RMQ||线段树)
- 【CSU1809】Parenthesis(线段树 + 贪心 + 前缀和)
- CSU 1809 Parenthesis(RMQ||线段树)
- CSU 1809 Parenthesis 思维,前缀RMQ
- CSU1809 Parenthesis(贪心+线段树)
- CSU 1809 Parenthesis(RMQ||线段树)
- CSU 1809 Parenthesis(RMQ||线段树)
- CSU 1809 Parenthesis(RMQ||线段树)
- CSU 1809 Parenthesis (线段树)
- 2016年湖南省第十二届大学生计算机程序设计竞赛 - G CSU 1809 Parenthesis (线段树)
- CSU 1809 Parenthesis(RMQ||线段树)
- CSU 1809 Parenthesis(RMQ||线段树)
- CSU 1809 Parenthesis(线段树前缀和)
- CSU 1809 Parenthesis(RMQ||线段树)
- CSU Problem 1809 Parenthesis(括号匹配,线段树,前缀和)——湖南省第十二届大学生计算机程序设计竞赛
- CSU 1809 Parenthesis(RMQ||线段树)
- CSU 1809 Parenthesis (线段树)【2016年湖南省第十二届大学生计算机程序设计竞赛 - G】