题目大意:已知一个长度为n的序列a1,a2,...,an。对于每个1<=i<=n,找到最小的非负整数p满足 对于任意的j, aj < = ai + p - sqrt(abs(i-j))
额,不写题解了,好像也不一定能写出来
直接上链接吧-> neither_nor的题解
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#define N 500010
using namespace std;
int a[N];
struct ppp {int w,l,r;}p[N];
double cal(int x,int now) {return a[x]+sqrt(abs(now-x));}
int ans1[N],ans2[N];
int main()
{
int n,i,j,x,y;
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
int h=1,t=0;
for(i=1;i<=n;i++)
{
p[h].l++;
if(h<=t&&p[h].l>p[h].r) h++;
while(t>=h&&cal(p[t].w,p[t].l)<=cal(i,p[t].l)) t--;
if(h>t)
{
t++;
p[t]=(ppp){i,i,n};
}
else
{
int l=p[t].l,r=p[t].r+1;
while(l<r)
{
int mid=(l+r)>>1;
if(cal(p[t].w,mid)<=cal(i,mid)) r=mid;
else l=mid+1;
}
p[t].r=l-1;
t++;
p[t]=(ppp){i,l,n};
}
ans1[i]=max(ceil(cal(p[h].w,i))-a[i],0.0);
}
for(i=1;i<=n/2;i++)
swap(a[i],a[n-i+1]);
h=1,t=0;
for(i=1;i<=n;i++)
{
p[h].l++;
if(h<=t&&p[h].l>p[h].r) h++;
if(h>t||cal(i,n)>cal(p[t].w,n))
{
while(t>=h&&cal(p[t].w,p[t].l)<=cal(i,p[t].l)) t--;
if(h>t)
{
t++;
p[t]=(ppp){i,i,n};
}
else
{
int l=p[t].l,r=p[t].r+1;
while(l<r)
{
int mid=(l+r)>>1;
if(cal(p[t].w,mid)<=cal(i,mid)) r=mid;
else l=mid+1;
}
p[t].r=l-1;
t++;
p[t]=(ppp){i,l,n};
}
}
ans2[i]=max(ceil(cal(p[h].w,i))-a[i],0.0);
}
for(i=1;i<=n;i++)
printf("%d\n",max(ans1[i],ans2[n-i+1]));
}