刚学二分栈,40pts求救
查看原帖
刚学二分栈,40pts求救
93701
Morgen_Kornblume楼主2021/6/22 23:35
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cctype>
//#define  long long
#define int long long
using namespace std;

inline int fr(){
	int val=0,sig=1;char ch=getchar();
	while(!isdigit(ch)){if(ch=='-')sig=-1;ch=getchar();}
	while( isdigit(ch)){val=(val<<3)+(val<<1)+ch-'0';ch=getchar();}
	return val*sig;
}

int n;
int a[500010];
double f[500010];
double ans[500010];

struct choice{
	int from,l,r;
	choice(int tp1=0,int tp2=0,int tp3=0){
		from=tp1;l=tp2;r=tp3;
	}	
}jc[500010];
int head,tail;

inline double calc(int from,int nowa){
	if(from>nowa)return 1e18;
	return a[from]*1.0+sqrt(1.0*(nowa-from))-1.0*a[nowa];
}

void dp(){
	head=tail=1;
	jc[head]=choice(1,2,n);
	f[1]=0;
	for(int i=2;i<=n;i++){
		
		while(head<=tail&&jc[tail].r<i)head++;
		
		f[i]=calc(jc[head].from,i);
		jc[head].l=i+1;
		
		ans[i]=max(ans[i],f[i]);
		
		int pos=-1;
		while(head<=tail&&calc(i,jc[tail].l)>=calc(jc[tail].from,jc[tail].l)){
			pos=jc[tail].l;
			tail--;	
		}
		if(head<=tail&&calc(i,jc[tail].r)<=(jc[tail].from,jc[tail].r)){
			int l=jc[tail].l,r=jc[tail].r;
			while(l<=r){
				int mid=(l+r)>>1;
				if(calc(i,mid)>=(jc[tail].from,mid)){
					r=mid-1;
					pos=mid;
				}
				else{
					l=mid+1;
				}
			}
			if(pos!=-1)jc[tail].r=pos-1;
		}
		if(pos!=-1){
			jc[++tail]=choice(i,pos,n);
		}
	}
}

signed main(){
	
	n=fr();
	
	for(int i=1;i<=n;i++){
		a[i]=fr();
	}
	
	dp();
	
	reverse(ans+1,ans+1+n);
	reverse(a+1,a+1+n);
	
	dp();
	
	for(int i=n;i>=1;i--){
		printf("%lld\n",(int)ceil(ans[i]));
	}
	return 0;
}
2021/6/22 23:35
加载中...