版权声明:Why is everything so heavy? https://blog.csdn.net/lzc504603913/article/details/82931334
链接:https://www.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个字符是第种括号。另外,如果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
解题思路:预处理,通常判断是否是正确的括号序都用栈去判断,那么我们就先判断整个串出否是括号序,在栈的变化过程中,我们用一个数组记录某时刻栈顶是哪个元素即可。最后我们判断栈顶是否相等,即可判断这个区间是否是括号序。
#include<iostream>
#include<algorithm>
#include<math.h>
#include<queue>
#include<string>
using namespace std;
const int MAXN=1000006;
vector<int> sta;
int pos[MAXN];
int a[MAXN];
int main(){
int N,M,Q;
scanf("%d%d%d",&N,&M,&Q);
for(int i=1;i<=N;i++)
scanf("%d",&a[i]);
for(int i=1;i<=N;i++){
if(sta.empty())
sta.push_back(i);
else if(a[i]/2==a[sta.back()]/2&&a[i]==a[sta.back()]+1)
sta.pop_back();
else
sta.push_back(i);
if(!sta.empty())
pos[i]=sta.back();
}
int l,r;
while(Q--){
scanf("%d%d",&l,&r);
if(pos[r]==pos[l-1])
printf("Yes\n");
else
printf("No\n");
}
return 0;
}