题目链接:https://www.luogu.com.cn/problem/P6510
题目描述:
奶牛在熊大妈的带领下排成了一条直队。
显然,不同的奶牛身高不一定相同……
现在,奶牛们想知道,如果找出一些连续的奶牛,要求最左边的奶牛A是最矮的,最右边的B是最高的,且B奶牛高于A奶牛。中间如果存在奶牛,则身高不能和A,B奶牛相同。问这样的奶牛最多会有多少头?
输入:第一行一个正整数N表示奶牛的头数。
输出:一行一个整数,表示最多奶牛数。
解题思路:我们要找到从后向前数第二个后缀最大值的位置k,A一定在该位置的右侧。并且只要A在k右侧,A是当前序列的后缀最小值,那么A就是一个正确的左端点。
具体代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define NO cout<<"NO"<<endl;
#define YES cout<<"YES"<<endl;
ll NUM=1e9+2;
const int maxn = 100005;
int n, ans, tx, tn;
int a[maxn], sx[maxn], sn[maxn];
int main() {
scanf("%d", &n);
for (int i=1;i<=n;++i) scanf("%d",a+i);
for (int i=1;i<=n;++i) {
while (tn && a[sn[tn]] >= a[i]) --tn;
////保持 sn 数组的元素所对应的 a 数组元素呈现单调递减的性质
while (tx && a[sx[tx]] < a[i]) --tx;
////保持 sx 数组的元素所对应的 a 数组元素呈现单调递增的性质
int k = upper_bound(sn+1, sn+1+tn, sx[tx])-sn;
////在[sn+1,sn+1+tn)区间中查找第一个大于 sx[tx] 的元素并计算长度
if (k!=(tn+1)) {
ans=max(ans, i - sn[k] + 1);
////就更新 ans 成为最大值;
}
sn[++tn]=i;
//// 将当前元素索引存储到 sn 数组中
sx[++tx]=i;
}//// 将当前元素索引存储到 sx 数组中
printf("%d\n", ans);
return 0;
}
标签:sx,tx,每日,排队,tn,sn,数组,奶牛
From: https://www.cnblogs.com/shenqimaomaoxia/p/18678423