1. 程式人生 > >牛客國慶集訓派對Day1 J-Princess Principal (區間查詢是否是正確的括號匹配)

牛客國慶集訓派對Day1 J-Princess Principal (區間查詢是否是正確的括號匹配)

阿爾比恩王國(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;
}