牛客国庆集训派对Day1 J题 Princess Principal (栈思维)

链接:https://ac.nowcoder.com/acm/contest/201/J
来源:牛客网
 

题目描述

阿尔比恩王国(the Albion Kingdom)潜伏着一群代号“白鸽队(Team White Pigeon)”的间谍。在没有任务的时候,她们会进行各种各样的训练,比如快速判断一个文档有没有语法错误,这有助于她们鉴别写文档的人受教育程度。
这次用于训练的是一个含有n个括号的文档。括号一共有m种,每种括号都有左括号和右括号两种形式。我们定义用如下的方式定义一个合法的文档:
1.一个空的字符串是一个合法的文档。
2.如果A,B都是合法的文档,那么AB也是合法的文档。
3.如果S是合法的文档,那么aSb也是合法的文档,其中a,b是同一种括号,并且a是左括号,b是右括号。
现在给出q个询问,每次询问只考虑文档第l至r个字符的情况下,文档是不是合法的。

输入描述:

第一行两个整数n,m,q(1 ≤ n,m,q ≤ 106)。
第二行有n个空格隔开的整数x,第i个整数xi(0 ≤ xi < m*2)代表文档中的第i个字符是第⌊x2⌋⌊x2⌋种括号。另外,如果xi是偶数,它代表一个左括号,否则它代表一个右括号。
接下来q行,每行两个空格隔开的整数l,r(1 ≤ l ≤ r ≤ n),代表询问第l至r个字符构成的字符串是否是一个合法的文档。

输出描述:

输出共q行,如果询问的字符串是一个合法的文档,输出"Yes",否则输出"No"。

示例1

输入

复制

6 4 3
0 2 3 1 4 7
1 4
1 5
5 6

输出

复制

Yes
No
No
#pragma GCC optimize(2)
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int maxn = 1e6 + 100;
const int inf = 0x3f3f3f3f;
typedef long long ll;
ll b[maxn];
ll c[maxn];
int main()
{
	freopen("C://input.txt", "r", stdin);
	int n, m, q;
	scanf("%d%d%d", &n, &m, &q);
	stacka;
	for (int i = 1; i <= n; i++)
	{
		scanf("%lld", &c[i]);
	}
	for (int i = 1; i <= n; i++)
	{
		if (a.empty() || !(c[i] & 1)) //栈为空或左括号
		{
			a.push(i);
		}
		if ((a.empty() && (c[i] & 1)))//栈为空且右括号
		{
			a.push(i);
		}
		if (c[i] & 1)//如果右括号
		{
			if (c[a.top()] == c[i] - 1)
			{
				a.pop();
			}
			else
			{
				a.push(i);
			}
		}
		if (a.empty())
		{
			b[i] = 0;
		}
		else
		{
			b[i] = a.top();   //b记录的就是当前指示的下标
		}                     //之后到这个位置之间的括号可以消除
	}
	for (int i = 1; i <= q; i++)
	{
		int x, y;
		scanf("%d%d", &x, &y);
		if (b[y] == b[x - 1])
		{
			printf("Yes\n");
		}
		else
		{
			printf("No\n");
		}
	}
	return 0;
}

解释一下样例:0 2 3 1 4 7
            0 2 3 1 4 7 
对应的括号:( (  ) ) ( )
对应的b数组:1 2 1 0 5 6
我们数组从1号位置开始。 b[4]=0,理解为从第0的位置之后到b[4]这个位置之间的括号都消除

你可能感兴趣的:(ACM)