RT,思路详见注释。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=100005;
ll n,a[N],l=1,f[N][30],p[N][30],ans;
unordered_map<ll,ll>mp;
int main(){
scanf("%lld",&n);
for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
memset(p,0x3f,sizeof(p));
for(int i=1;i<=n;i++)f[i][0]=a[i],p[i][0]=a[i];
for(int j=1;j<=20;j++){//最大值,判断最高
for(int i=1;i+(1<<(j-1))<=n+1;i++){
f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);
}
}
for(int j=1;j<=20;j++){//最小值,判断最矮
for(int i=1;i+(1<<(j-1))<=n+1;i++){
p[i][j]=min(p[i][j-1],p[i+(1<<(j-1))][j-1]);
}
}
mp[a[l]]++;
for(int r=2;r<=n;r++){
mp[a[r]]++;
bool flag=1;
while(flag&&l<r){//更新左端点
ll k=log2(r-l+1);//查询当前区间最矮高度
ll _min=min(p[l][k],p[r-(1<<k)+1][k]);
if(_min!=a[l]||mp[a[l]]>1){//如果最左边不是最矮或者中间有同样的高度,就将左端点加一
mp[a[l]]--;
l++;
}
else flag=0;
}
ll k=log2(r-l+1);
ll _max=max(f[l][k],f[r-(1<<k)+1][k]);
//cout<<l<<" "<<r<<endl;
if(a[l]!=a[r]&&a[l]<a[r]&&mp[a[r]]==1&&_max==a[r])ans=max(ans,r-l+1);//如果右端点合法,更新答案
//cout<<ans<<endl;
}
printf("%lld",ans);
return 0;
}