牛客國慶集訓派對Day1 J-Princess Principal (區間查詢是否是正確的括號匹配)
阿新 • • 發佈:2018-12-13
阿爾比恩王國(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; }