二分队列求调 已老实 90pts
查看原帖
二分队列求调 已老实 90pts
638537
g1ove楼主2024/10/31 15:10
#include<bits/stdc++.h>
#define ll long long
#define pb emplace_back
#define N 500005
using namespace std;
int n,a[N];
double f[N];
struct node{
	int l,r,p;
}q[N];
int l,r; 
double w(int l,int r){return sqrt(r-l)+a[l];}
int getp(int l,int r,int p,int newp)
{
	while(l<=r)
	{
		int mid=(l+r)/2;
		if(w(p,mid)>=w(newp,mid)) l=mid+1;
		else r=mid-1;
	}
	return l-1;
}
void solve()
{
	l=1,r=0;
	q[++r]=(node){1,n,0};
	for(int i=1;i<=n;i++)
	{
		f[i]=max(w(q[l].p,i),f[i]);
		q[l].l++;
		if(q[l].l>q[l].r) ++l;
		while(l<=r&&w(q[r].p,q[r].l)<=w(i,q[r].l)) --r;
		if(l>r) q[++r]=(node){i+1,n,i};
		else
		{
			int pos=getp(q[r].l,q[r].r,q[r].p,i);
			q[r].r=pos;
			if(pos<n)q[++r]=(node){pos+1,n,i};
		}
	}
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	solve();
	reverse(a+1,a+1+n);
	reverse(f+1,f+1+n);
	solve();
	reverse(a+1,a+1+n);
	reverse(f+1,f+1+n);
	for(int i=1;i<=n;i++) printf("%d\n",int(ceil(f[i]))-a[i]);
	return 0;
}
2024/10/31 15:10
加载中...