70pts 求助
查看原帖
70pts 求助
356925
快斗游鹿楼主2022/8/12 22:38

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;
}

2022/8/12 22:38
加载中...