单调栈模板题 luogu P2659
Posted 6262369sss
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单调栈模板题 luogu P2659相关的知识,希望对你有一定的参考价值。
题目链接:https://www.luogu.org/problem/P2659
实际上就是要我们求出每个数字左右两边第一个小于它的数字位置,然后两个位置所在的开区间长度乘以这个数字,取最大值输出。
因为是求两边第一个小于a[i]的数字,所以我们弄一个递增(其实是不减小就可以了,可以有相同大小的元素)的单调栈,从栈底到栈顶的数字是依次增大的,在求的过程中要始终保持递增的性质。我们每次在数字入栈时求出数字左边第一个小于它的数字位置,在出栈的时候求出右边第一个小于它的数字位置,为什么是这样,看下面,我这里的栈保存的是元素下标,而不是元素值。
L[i]记录左边第一个小于a[i]的元素位置(下标),没有就是0,R[i]记录右边第一个小于a[i]的元素位置,没有就是n+1。
对于一个a[i],假如a[i]大于栈顶元素(我的栈存的是下标,我们比较是就拿这个下标的值比较),那么如果把a[i]压入栈顶,这个栈还是递增的,这个时候栈顶元素就是第一个小于a[i]的数字,我们直接把L[i]赋值为栈顶元素就行了。
对于a[i]等于栈顶元素的情况,假如说值都是5好吧,那么其实栈顶的5在它入栈的时候,它的L数组值(它左边第一个小于它的元素位置)我们一定会先得到对吧,那么当前的a[i](也是5),它的L数组值肯定等于栈顶元素的L数组值吧,因为他俩相等,所以直接把a[i]的L数组值赋值为栈顶元素的数组值就可以了,在把a[i]入栈。
假如a[i]小于栈顶元素,那么如果我们把a[i]压入栈中,那么这个栈里面的元素就不单调递增了,所以说我们需要把栈里面比a[i]大的元素都弹出,假如现在我们要弹出当前栈顶元素,那么其实现在a[i]就是栈顶元素右边的第一个小于栈顶元素的值,所以我们这个时候可以直接把R[s.top()]赋值为i,这样每当我们出栈一个元素,这个元素的左右两边第一个小于它的元素位置就都找到了(左边的在进栈就找到了)。
然后,就没了。
我自己写的板子,应该木有问题,就是慢了点:
#include<iostream> #include<cstring> #include<algorithm> #include<queue> #include<map> #include<stack> #include<cmath> #include<vector> #include<set> #include<cstdio> #include<string> #include<deque> using namespace std; typedef long long LL; #define eps 1e-8 #define INF 0x3f3f3f3f #define maxn 2000005 stack<int>q; int n,m,k,t; int a[maxn]; int L[maxn],R[maxn]; inline int read() int f=1,x=0;char ch; doch=getchar();if(ch==‘-‘)f=-1;while(ch<‘0‘||ch>‘9‘); dox=x*10+ch-‘0‘;ch=getchar();while(ch>=‘0‘&&ch<=‘9‘); return f*x; int main() n=read(); for(int i=1;i<=n;i++) a[i]=read(); for(int i=1;i<=n;i++)//线性扫一遍 while(!q.empty()&&a[q.top()]>a[i])//先检查栈顶元素大于a[i]的情况 int s=q.top(); //保存一下栈顶元素值(下标) R[s]=i; //得到栈顶元素右边第一个小于它的元素下标 q.pop(); //出栈 if(q.empty()) //假如栈为空 L[i]=0; else if(a[q.top()]==a[i]) //假如栈顶元素等于a[i],那么L[i]就赋值为栈顶元素的L数组值 L[i]=L[q.top()]; else //栈顶元素小于a[i],把a[i]入栈 L[i]=q.top(); q.push(i); while(!q.empty())//最后栈顶可能还有元素没有出栈,这个时候他们的R数组值都是n+1,因为右边没有比他们小的值了 int s=q.top(); R[s]=n+1; q.pop(); LL ans=0; for(int i=1;i<=n;i++) ans=max(ans,(LL)a[i]*(R[i]-L[i]-1)); printf("%lld\n",ans); return 0;
以上是关于单调栈模板题 luogu P2659的主要内容,如果未能解决你的问题,请参考以下文章