Patrik 音乐会的等待 单调栈的迷茫回忆

STL 必定要学好 必定要学好,必定要学好!!!node

题目连接:https://www.luogu.org/problemnew/show/P1823spa

 

咱们须要单向查找;用单调栈;code

思路:
维护一个身高单调递减的栈,若是下一个比上一个插入的矮,就直接进栈,若是如今插入的比上一个高,咱们就要更新答案的值;
blog

由于如今要插入的人会挡住前面比他矮的人,因此前面比他矮的人就不能再看见之后的人了;get

固然还要记录前面和他同样高的人的个数,由于和他同样高的人是能够看见他后面的人的(题目中是大于没有等于)string

由于咱们维护的是右端点的值,因此前面的矮人就直接弹出;it

代码io

#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
using namespace std;
const int maxn=500050;
stack <int> s;//单调栈 
int n,x,ans;
int a[maxn];
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        int t=1;//记录和他身高同样的人的个数 
        scanf("%d",&x);
        while(s.size()&&x>=s.top())//栈中还有人而且有人比他矮或等高 
        {
            if(x==s.top()) t++;
            ans++;s.pop();//由于不弹出就不能查看上一个值,因此即便等高也要弹出 
        }
        if(s.size()) ans++;//若是前面有人比他高,那么他们两我的也能互相看到 
        while(t--) s.push(x);//将全部不应弹出的等高的人加入栈 
    }
    printf("%d",ans);
    
    return 0;
}

对不起,TLEclass

显然咱们处理等高的人的时候浪费了大把的时间,因此咱们能够把前面和他等高的人的贡献直接加到如今要插入人的身上top

用结构体就好了

 

代码

#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
using namespace std;
const int maxn=500050;

struct node
{
    int h;//高度 
    long long num;//前面等高人的个数 
};
stack <node> s;
int n,x;
long long ans;
int a[maxn];
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&x);
            node p=(node){x,1};//记录当前和他等高的人是本身 
        while(s.size()&&x>=s.top().h)
        {
            if(x==s.top().h) p.num+=s.top().num;
            ans+=s.top().num;s.pop();
        }
        if(s.size()) ans++;
        s.push(p);
    
    }
    printf("%lld",ans);
    
    return 0;
}

 

STL 不会,手写两行泪;

相关文章
相关标签/搜索