#单调栈#洛谷 6510 奶牛排队
题目
问长度超过1的最长的区间\([i,j]\)满足区间最小值为\(a_i\),
区间最大值为\(a_j\),且其余数在区间\((a_i,a_j)\)范围内,没有输出0
分析
枚举右端点,考虑维护一个单调递增和一个单调不递增的的单调栈,
那么单调不递增的栈顶一定不小于右端点的值,
那么在单调递增的点中选择栈顶位置的后继即为左端点,
这样保证了左端点尽量小,并且左端点与右端点之间
不存在任意数超过右端点的值或小于左端点的值
代码
#include <cstdio>
#include <cctype>
#include <algorithm>
#define rr register
using namespace std;
const int N=100011;
int n,a[N],stmn[N],stmx[N],ans,topmx,topmn;
inline signed iut(){
rr int ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
inline void print(int ans){
if (ans>9) print(ans/10);
putchar(ans%10+48);
}
signed main(){
n=iut();
for (rr int i=1;i<=n;++i) a[i]=iut();
for (rr int i=1;i<=n;++i){
while (topmn&&a[stmn[topmn]]>=a[i]) --topmn;
while (topmx&&a[stmx[topmx]]<a[i]) --topmx;
rr int pos=upper_bound(stmn+1,stmn+1+topmn,stmx[topmx])-stmn;
if (pos<=topmn) ans=max(ans,i-stmn[pos]+1);
stmn[++topmn]=stmx[++topmx]=i;
}
return !printf("%d",ans);
}