PIPIOJ 1475: PIPI打怪Ⅲ 单调栈 思维

http://pipioj.online/problem.php?id=1475
在这里插入图片描述

思路:对于任意一个数 a i a_i ai,若我们知道在它左侧的第一个小于它的数 a l a_l al,在它右侧的第一个小于它的数 a r a_r ar,那么当区间被限制到 ( l , r ) (l,r) (l,r)内且包含 a i a_i ai时,这个区间的最小值一定是 a i a_i ai。不妨设 a n s j ans_j ansj表示区间长度为 j j j时的最大价值,那么显然我们要做一个更新操作: a n s j = m a x ( a n s j , a i ) , 1 < = j < = r − l − 1 ans_j=max(ans_j,a_i),1<=j<=r-l-1 ansj=max(ansj,ai),1<=j<=rl1。那么问题就简单了,如何快速求出一个数左右两侧第一个小于(大于)它的坐标?单调栈模板题;如何快速更新?不难发现,每次更新都是对 [ 1 , r − l − 1 ] [1,r-l-1] [1,rl1]进行更新,那么就会有一个隐藏的条件:对于任意的 i i i,都有 a n s i > = a n s i − 1 ans_i>=ans_{i-1} ansi>=ansi1成立,所以我们每次仅仅需要更新一个值: a n s r − l − 1 = m a x ( a n s r − l − 1 , a i ) ans_{r-l-1}=max(ans_{r-l-1},a_i) ansrl1=max(ansrl1,ai),最后扫一遍 a n s ans ans维护它的单调性即可。

#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;

const int maxn=1e6+5;

int n,m,q;
int a[maxn],lless[maxn],rless[maxn],ans[maxn];

int main()
{
    
    
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    a[0]=a[n+1]=-1;
    stack<int> s;
    for(int i=1;i<=n+1;i++)
    {
    
    
        if(s.empty()||a[i]>=a[s.top()])
            s.push(i);
        else
        {
    
    
            while(!s.empty()&&a[i]<a[s.top()])
            {
    
    
                rless[s.top()]=i;
                s.pop();
            }
            s.push(i);
        }
    }
    for(int i=n;i>=0;i--)
    {
    
    
        if(s.empty()||a[i]>=a[s.top()])
            s.push(i);
        else
        {
    
    
            while(!s.empty()&&a[i]<a[s.top()])
            {
    
    
                lless[s.top()]=i;
                s.pop();
            }
            s.push(i);
        }
    }
    for(int i=1,len;i<=n;i++)
    {
    
    
        len=rless[i]-lless[i]-1;
        ans[len]=max(ans[len],a[i]);
    }
    for(int i=n-1;i>=1;i--)
        if(ans[i]<ans[i+1])
            ans[i]=ans[i+1];
    scanf("%d",&m);
    while(m--)
    {
    
    
        scanf("%d",&q);
        printf("%d\n",ans[q]);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/xiji333/article/details/114449960