单调栈模板题

题意

N个人正在排队进入一个音乐会。人们等得很无聊,于是他们开始转来转去,想在队伍里寻找自己的熟人。队列中任意两个人A和B,如果他们是相邻或他们之间没有人比A或B高,那么他们是可以互相看得见的。

写一个程序计算出有多少对人可以互相看见。


解析

维护一个不升的序列(单调栈…?)


#include 
#include 

#define Rep( i , _begin , _end ) for(int i=(_begin),i##_END = (_end);i<=i##_END;i++)
#define For( i , _begin , _end ) for(int i=(_begin),i##_END = (_end);i!=i##_END;i++)
#define Lop( i , _begin , _end ) for(int i=(_begin),i##_END = (_end);i>=i##_END;i--)
#define Dnt( i , _begin , _end ) for(int i=(_begin),i##_END = (_end);i!=i##_END;i--)

using std :: max;
using std :: min;
using std :: sort;

const int maxx = 500000 + 25;

int a[maxx],d[maxx];
int n,m,x,y,z,ans,top,cnt;

int main(){
    scanf("%d",&n);
    Rep( i , 1 , n ) scanf("%d",&a[i]);
    Rep( i , 1 , n ){
        int tmp = top;
        while(a[i] >= d[tmp] && tmp){
            ans ++;
            tmp --;
        }
        if(tmp) ans ++;
        while(top && d[top] < a[i]) top --;
        top ++;
        d[top] = a[i];
    }
    printf("%d\n",ans);
    return 0;
}

你可能感兴趣的:(模板与总结,单调栈)