ST表和二分,枚举右端点 r,找最左边的 l 使得 a[r] 为区间最大值,然后找 [l,r] 的第一个后缀最小值出现位置。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<stack>
#include<map>
using namespace std;
#define ri register int
#define rd(n) n=read()
inline int read(void)
{
register int res=0,f=0;
register char c=getchar();
while(c<'0'||c>'9'){f^=(c=='-');c=getchar();}
while(c>='0'&&c<='9'){res=(res<<3)+(res<<1)+(c^48);c=getchar();}
return f?-res:res;
}
inline void fprint(int n)
{
if(n<0){putchar('-');n=-n;}
if(n>9) fprint(n/10);
putchar(n%10+'0');
}
inline void print(int n)
{
fprint(n);
putchar('\n');
}
const int N=100002;
int n,m,k,x,y,z,ans,res,l,r,a[N];
stack<int>s;
map<int,int>id;
vector<int>pos[N];
int Log[N],ma[N][16],mi[N][16];
void ST(void)
{
for(ri i=2;i<=n;++i) Log[i]=Log[i>>1]+1;
for(ri i=1;i<=n;++i) ma[i][0]=mi[i][0]=a[i];
k=Log[n];
for(ri i=1;i<=k;++i)
{
for(ri j=1;j<=n-(1ll<<i)+1;++j)
{
ma[j][i]=max(ma[j][i-1],ma[j+(1ll<<(i-1))][i-1]);
mi[j][i]=min(mi[j][i-1],mi[j+(1ll<<(i-1))][i-1]);
}
}
}
inline int queryma(int l,int r)
{
k=Log[r-l+1];
return max(ma[l][k],ma[r-(1ll<<k)+1][k]);
}
inline int querymi(int l,int r)
{
k=Log[r-l+1];
return min(mi[l][k],mi[r-(1ll<<k)+1][k]);
}
signed main(void)
{
rd(n);
for(ri i=1;i<=n;++i) rd(a[i]);
for(ri i=1;i<=n;++i) pos[i].emplace_back(0);
for(ri i=1;i<=n;++i)
{
if(id.find(a[i])==id.end()) id[a[i]]=++m;
pos[id[a[i]]].emplace_back(i);
}
ST();
for(ri i=1;i<=n;++i)
{
x=id[a[i]];
y=*--lower_bound(pos[x].begin(),pos[x].end(),i);
//y is the first pos before i that value[y]=value[i]
++y;//A<B a[y]==a[i]
//cout<<queryma(y,i)<<"\n";
if(queryma(y,i)>a[i])
{
res=y;
l=y; r=i;
while(l<=r)
{
ri mid=(l+r)>>1;
if(queryma(mid,i)>a[i]) l=mid+1;
else
{
res=mid;
r=mid-1;
}
}
y=res;
}
//let a[i] become the maximum of range [y,i]
//cout<<y<<' '<<i<<"\n";
ri ts=querymi(y,i);
ri tt=id[ts];
ri ttt=*--lower_bound(pos[tt].begin(),pos[tt].end(),i);
// ttt is the first pos that a[ttt]==min value of range [y,i]
//cout<<ttt<<"\n";
if(ttt>=y) ans=max(ans,i-ttt+1);
}
print(ans);
return 0;
}