【题解】P6510 奶牛排队
题面
前言
呜呜呜,云落好菜
正文
圆规正传
我们枚举 \(B\)
那么 \(A\) 一定是 \(1-B\) 的后缀最小值的位置
并且由于 \(B\) 要是区间最大值,也就是说,第二个后缀最大值的位置一定在 \(A\) 左面
那么我们就通过 第二个后缀最大值的位置,二分出最靠右的 \(A\) 的位置
上面的后缀最大值和后缀最小值就用单调栈求
代码
#include<iostream>
#include<stack>
using namespace std;
const int maxn=1e5+10;
int n,a[maxn];
int stk1[maxn],tp1,stk2[maxn],tp2;
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n;
int ans=0;
for(int i=1;i<=n;i++){
cin>>a[i];
while(tp1&&a[stk1[tp1]]<a[i]){
tp1--;
}
while(tp2&&a[stk2[tp2]]>a[i]){
tp2--;
}
int l=1,r=tp2,pos=0;
while(l<=r){
int mid=l+r>>1;
if(stk2[mid]>stk1[tp1]){
r=mid-1;
}else{
l=mid+1;
}
}
pos=l;
if(pos!=tp2+1){
ans=max(ans,i-stk2[pos]+1);
}
stk1[++tp1]=i;
stk2[++tp2]=i;
}
cout<<ans<<endl;
return 0;
}
后记
日常二分写炸虚空调试
完结撒花!