链接: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;
}



 

 

10-03 13:39