手写单调栈RE求调
查看原帖
手写单调栈RE求调
787424
Capoien_xie_bei_Chen楼主2023/11/7 22:26

Rt,不是调题目,是找RE的地方,可以可定是手写栈的问题。

题目是站外题就不发了。

#include<bits/stdc++.h>
#define ls k<<1
#define rs k<<1|1
using namespace std;
typedef long long LL;
const int N=2000005;
int n,L[N],R[N];
LL a[N],ans=0ll;
int top_L=0,top_R=0;
int stL[N<<3],stR[N<<3];
struct segment{
	int L[N<<3],R[N<<3];
	LL mn[N<<3],mx[N<<3];
	void pushup_mx(int k){mx[k]=max(mx[ls],mx[rs]);}
	void pushup_mn(int k){mn[k]=min(mn[ls],mn[rs]);}
	void build(int k,int l,int r){
		L[k]=l,R[k]=r;
		if(l==r){mx[k]=mn[k]=a[l];return;}
		int mid=(l+r)>>1;
		build(ls,l,mid);
		build(rs,mid+1,r);
		pushup_mx(k);
		pushup_mn(k);
	}
	LL ask_mx(int k,int l,int r){
		if(R[k]<l||L[k]>r) return 0;
		if(L[k]>=l&&R[k]<=r) return mx[k];
		return max(ask_mx(ls,l,r),ask_mx(rs,l,r));
	}
	LL ask_mn(int k,int l,int r){
		if(R[k]<l||L[k]>r) return 1e18;
		if(L[k]>=l&&R[k]<=r) return mn[k];
		return min(ask_mn(ls,l,r),ask_mn(rs,l,r));
	}
}seg;
void solve(){
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
	seg.build(1,1,n);
	for(int i=1;i<=n;i++){
		while(top_L&&a[top_L]>=a[i]) top_L--;
		if(top_L) L[i]=stL[top_L]+1;
		else L[i]=1;
		stL[++top_L]=i;
	}
	for(int i=n;i;i--){
		while(top_R&&a[top_R]>=a[i]) top_R--;
		if(top_R) R[i]=stR[top_R]-1;
		else R[i]=n;
		stR[++top_R]=i;
	}
	for(int i=1;i<=n;i++) ans=max(ans,a[i]*seg.ask_mx(1,L[i],R[i])*(R[i]-L[i]+1));
	top_L=top_R=0;
	for(int i=1;i<=n;i++){
		while(top_L&&a[top_L]<=a[i]) top_L--;
		if(top_L) L[i]=stL[top_L]+1;
		else L[i]=1;
		stL[++top_L]=i;
	}
	for(int i=n;i;i--){
		while(top_R&&a[top_R]<=a[i]) top_R--;
		if(top_R) R[i]=stR[top_R]-1;
		else R[i]=n;
		stR[++top_R]=i;
	}
	for(int i=1;i<=n;i++) ans=max(ans,1ll*a[i]*seg.ask_mn(1,L[i],R[i])*(R[i]-L[i]+1));
	cout<<ans<<"\n";
}
signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	/*int tt;cin>>tt;while(tt--)*/solve();
	return 0;
}
2023/11/7 22:26
加载中...