HHU Mouse and Parenthesis (线段树+括号匹配)



问题 E: Mouse and Parenthesis

时间限制:  1 Sec   内存限制:  128 MB
提交:  46   解决:  10
[ 提交 ][ 状态 ][ 讨论版 ]

题目描述

Tom has m same balanced parenthesis sequence P=p1 p2…pn of length n.

This day Jerry comes into Tom's room and swaps one pair of parenthesis in every sequence.

Tom and Jerry both like balanced parenthesis sequence, so Jerry wants to know whether each P remains balanced after pai and pbi  swapped. 


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').

输入

The first line contains an integers T (T≤20), which indicates the number of test cases. 

For each case:

The first line contains two integers n,m.
The second line contains n characters p1 p2…pn.

The i-th of the last m lines contains 2 integers ai,bi (1≤ai,bi≤n,ai≠bi).


⋅ for 50% data, 1≤n≤50,1≤q≤1000.

⋅ for 100% data, 1≤n≤100000,1≤q≤100000.

输出

For every test case, you should output "Case #x:", where x indicates the case number and counts from 1. Then in i th line output 'Yes' if i th parenthesis sequence is balanced, otherwise 'No'. 

样例输入

2
4 2
(())
1 3
2 3
2 1
()
1 2

样例输出

Case #1:
No
Yes
Case #2:
No
总结:

通过思考我们将交换的情况分开讨论,就会发现如果交换的是相同的yes,)(交换一定也是yes,那么就差()变成)(情况,这就涉及到一个括号怎样才是合法的,因为题目中给出了,原本序列是合法的这个条件,所以保证了,()的数量相等;

我们发现)合法的条件是他之前存在大于等于1的未匹配的(,而(永远是合法的,交换以后一定要注意可能不合法的部分出现在[a,b-1],而如果这里的)前面的(小于2(为啥是小于2呢,因为用(换),这部分的)前面的(都少了一个,还多了一个)匹配掉一个(,所以少了两个()但是我们如果我们每次遍历[a,b-1]这个区间会超时,所以我们用线段树来维护区间的最小值

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int maxn=100000+10;
string a;
int num[maxn],n,m;
struct node
{
	int s;
	int e;
	int value;
}nodes[4*maxn];
int min(int a,int b)
{
	if(a<b) return a;
	else return b;
}
int init(int s,int e,int index)
{
	nodes[index].s=s;
	nodes[index].e=e;
	if(s==e) 
	{
		nodes[index].value=num[s];
		return num[s];
	}
	int m=(s+e)/2;
	nodes[index].value=min(init(s,m,2*index),init(m+1,e,2*index+1));
	return nodes[index].value;
}
int query(int s,int e,int index)
{
	int m=(nodes[index].s+nodes[index].e)/2;
	if(s==nodes[index].s&&e==nodes[index].e) return nodes[index].value;
	else if(nodes[index].s<=s&&e<=m) return query(s,e,2*index);
	else if(s>=m+1&&e<=nodes[index].e) return query(s,e,2*index+1);
	else return min(query(s,m,2*index),query(m+1,e,2*index+1));
}


int main()
{
	//freopen("input.txt","r",stdin);
	int T;
	scanf("%d",&T);
	for(int t=1;t<=T;t++)
	{
		memset(num,0,sizeof(num));
		scanf("%d%d",&n,&m);
		printf("Case #%d:\n",t);
		cin>>a;
		int temp=0;
		for(int i=0;i<a.size();i++)
		{
			if(a[i]=='(') temp++;
			else temp--;
			num[i]=temp;
		}
		//buildtree(0,n-1,1);
		init(0,n-1,1);
		for(int i=1;i<=m;i++)
		{
			int p1,p2;
			scanf("%d%d",&p1,&p2);
			if(p1>p2)
			{
				temp=p1;
				p1=p2;
				p2=temp;
			}
			p1--;
			p2--;
			if(a[p1]==a[p2]) printf("Yes\n");
			else if(a[p1]=='('&&a[p2]==')')
			{
				if(query(p1,p2-1,1)<2) printf("No\n");
				else printf("Yes\n");
			}
			else printf("Yes\n");
		}
	}
	return 0;
}


问题 E: Mouse and Parenthesis

时间限制:  1 Sec   内存限制:  128 MB
提交:  46   解决:  10
[ 提交 ][ 状态 ][ 讨论版 ]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值