1. 程式人生 > >upc國慶集訓第八天 Princess Principal(思維+棧)

upc國慶集訓第八天 Princess Principal(思維+棧)

問題 H: Princess Principal

時間限制: 2 Sec  記憶體限制: 1024 MB
提交: 183  解決: 37
[提交] [狀態] [討論版] [命題人:admin]

題目描述

阿爾比恩王國(the Albion Kingdom)潛伏著一群代號“白鴿隊(Team White Pigeon)”的間諜。在沒有任務的時候,她們會進行各種各樣的訓練,比如快速判斷一個文件有沒有語法錯誤,這有助於她們鑑別寫文件的人受教育程度。

這次用於訓練的是一個含有n個括號的文件。括號一共有mm種,每種括號都有左括號和右括號兩種形式。我們定義用如下的方式定義一個合法的文件:

1.一個空的字串是一個合法的文件。
2.如果A,B都是合法的文件,那麼AB也是合法的文件。
3.如果S是合法的文件,那麼aSb也是合法的文件,其中a,b是同一種括號,並且a是左括號,b是右括號。
現在給出q個詢問,每次詢問只考慮文件第ll至rr個字元的情況下,文件是不是合法的。

輸入

第一行兩個整數n,m,q(1≤n,m,q≤106)。
第二行有n個空格隔開的整數x,第i個整數xi(0≤xi<m∗2)代表文件中的第i個字元是第⌊x/2⌋種括號,且如果xi是偶數,它代表一個左括號,否則它代表一個右括號。
接下來q行,每行兩個空格隔開的整數l,r(1≤l≤r≤n),代表詢問第l至r個字元構成的字串是否是一個合法的文件。

輸出

輸出共q行,如果詢問的字串是一個合法的文件,輸出"Yes",否則輸出"No"。

樣例輸入

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

樣例輸出

Yes
No
No

題解:可以用一個數組來記錄每個位置與哪個位置進行的配對,然後用棧來模擬配對過程,最後再遞推到最多可以配對到的位置即可

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> PII;
const int maxn=1e6+7;
#define inf 0x3f3f3f3f
 
int a[maxn],dp[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]);
 
    stack<pair<int,int> >s;
 
    for(int i=1;i<=n;i++)
    {
        if(s.empty())
            s.push(make_pair(a[i],i));
        else if(a[i]/2==s.top().first/2 && a[i]==s.top().first+1)
        {
            dp[s.top().second]=i;
            dp[i]=s.top().second;
            s.pop();
        }
        else s.push(make_pair(a[i],i));
    }
 
    for(int i=n;i>=1;i--)
        if(a[i]%2==0)
            dp[i]=max(dp[ dp[i]+1 ],dp[i]);
 
    for(int i=1;i<=n;i++)
        if(a[i]%2)
            dp[i]=min(dp[i],dp[ dp[i]-1  ] );
 
    //printf("%d %d\n",dp[2],dp[5]);
    for(int i=1;i<=q;i++)
    {
        int l,r;
        scanf("%d%d",&l,&r);
        if(dp[l]>=r && dp[r]<=l)
            printf("Yes\n");
        else
            printf("No\n");
    }
    return 0;
}