您的位置:首页 > 其它

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 of
length 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