决策单调性求调
查看原帖
决策单调性求调
300078
pengyule楼主2022/2/17 18:29
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,l,r,h[N],f[N],g[N],_sqrt[N];
struct J {
	int x,l,r;
}q[N];
void solve(int h[],int f[]){
	l=1,r=0;q[++r]={1,1,n};
	for(int i=2;i<=n;i++){
		while(l<=r&&q[l].r<i)l++;
		q[l].l=i;
		f[i]=h[q[l].x]+_sqrt[i-q[l].x];
		int pos=-1;
		while(l<=r&&(h[q[r].x]+_sqrt[q[r].l-q[r].x])<=(h[i]+_sqrt[q[r].l-i]))pos=q[r].l,r--;
		if(l<=r&&(h[q[r].x]+_sqrt[q[r].r-q[r].x])<=(h[i]+_sqrt[q[r].r-i])){
			int L=q[r].l-1,R=q[r].r+1,mid;
			while(L<R-1){
				mid=L+R>>1;
				if((h[q[r].x]+_sqrt[mid-q[r].x])<=(h[i]+_sqrt[mid-i]))R=mid;
				else L=mid;
			}
			pos=R;
		}
		q[++r]={i,pos,n};
	}
}
int main(){
	cin>>n;
	for(int i=1;i<=n;i++)cin>>h[i];
	int j=1,_;
	for(int i=1;i<=n;i++){
		_=sqrt(i);
		if(_*_==i)while(j<=i)_sqrt[j++]=_; 
	}
	while(j<=n)_sqrt[j++]=_+1;
	solve(h,f);
	reverse(h+1,h+n+1);
//	for(int i=1;i<=n;i++)cout<<ceil(f[i])<<' ';puts("");
	solve(h,g);
	reverse(h+1,h+n+1);
	reverse(g+1,g+n+1);
//	for(int i=1;i<=n;i++)cout<<ceil(g[i])<<' ';puts("");
	for(int i=1;i<=n;i++)cout<<max(f[i],g[i])-h[i]<<'\n';
}
2022/2/17 18:29
加载中...