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;
}

猜你喜欢

转载自blog.csdn.net/sudu6666/article/details/82960628