P3515

[POI2011]Lightning Conductor

分析一手这个东西:

$$a_j\le a_i+p(i)-\sqrt{|i-j|}\Leftrightarrow p(i)\ge a_j-a_i+\sqrt{|i-j|}$$

于是我们设 $f(i)=\max_{j\in [1,n]}\{a_j-a_i+\sqrt{|i-j|}\}$,则 $p(i)=\lceil f(i)\rceil$。

然后这个绝对值很烦人,我们想办法给它分类讨论掉。

不妨设 $j\le i$,那么就有:

$$f(i)=\max_{j=1}^{i}\{a_j-a_i+\sqrt{i-j}\}$$

此时我们设权函数 $w(j,i)=a_j-a_i+\sqrt{i-j}$,尝试证明其满足四边形不等式。

即证明:$w(i,j+1)+w(i+1,j)\le w(i,j)+w(i+1,j+1)$。

代入我们权函数的定义式,并消去相同项,我们需要证:

$$\sqrt{j-i+1}+\sqrt{j-i-1}\le 2\sqrt{j-i}$$

好像 $j-i$ 可以当作一个整体,不妨设其为 $x$,则我们要证:

$$\sqrt{x+1}+\sqrt{x-1}\le 2\sqrt{x}$$

两边平方,我们需要证:

$$\sqrt{x^2-1}\le x$$

这是显然的,所以我们得到 $w$ 满足四边形不等式。

到这里我们就可以着手做题了,但我还是想用求导再证一下(不感兴趣的可以忽略这种证明):

回到 $\sqrt{x+1}+\sqrt{x-1}\le 2\sqrt{x}$ 这个式子,将其改为:

$$\sqrt{x+1}-\sqrt{x}\le \sqrt{x}-\sqrt{x-1}$$

我们可以通过证明 $f(x)=\sqrt{x+1}-\sqrt{x}$ 是一个单调不增函数来得到这个式子。

那么一个比较好的方式就是求导:

$$f’(x)=\dfrac{1}{2\sqrt{x+1}}-\dfrac{1}{2\sqrt{x}}<0$$

所以说这玩意就是单调递减的。

证明其满足四边形不等式之后,我们回到 $f$ 的定义:

$$f(i)=\max_{j=1}^{i}\{w(j,i)\}$$

由决策单调性定理(的推广),得到 $f(i)$ 满足决策单调性。

然后我们要做的就是如何利用决策单调性来优化,这里使用分治。

具体讲一下流程:假设 $f(x)$($x\in [l,r]$)的最优决策点在 $[k_l,k_r]$,这个时候我们设 $mid=(l+r)/2$,暴力求出 $mid$ 的决策点 $k$,根据决策单调性将区间分成 $[l,mid-1]$ 和 $[mid+1,r]$ 两段,其最优决策点所在的区间分别为 $[kl,k]$ 和 $[k,kr]$。

用一下主定理就能知道这个复杂度是对的。。。

反过来的话像上面一样推就好了,仍然可以得到:

$$f(i)=\max_{j=n}^{i}\{w’(i,j)\}$$

其中 $f(i)$ 是满足决策单调性的,且决策点随 $i$ 的减小而减小。

时间复杂度 $O(n\log n)$。

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include<iostream>
#include<cstdio>
#include<cmath>
#define ll long long
#define ld long double
using namespace std;
namespace Ehnaev{
inline ll read() {
ll ret=0,f=1;char ch=getchar();
while(ch<48||ch>57) {if(ch==45) f=-f;ch=getchar();}
while(ch>=48&&ch<=57) {ret=(ret<<3)+(ret<<1)+ch-48;ch=getchar();}
return ret*f;
}
inline void write(ll x) {
static char buf[22];static ll len=-1;
if(x>=0) {do{buf[++len]=x%10+48;x/=10;}while(x);}
else {do{buf[++len]=-(x%10)+48;x/=10;}while(x);}
while(len>=0) putchar(buf[len--]);
}
}using Ehnaev::read;using Ehnaev::write;
inline void writeln(ll x) {write(x);putchar(10);}

const ll N=5e5;

ll n,ans;
ld f[N+5],f_[N+5],a[N+5];

inline ld W(ll x,ll y) {return a[x]-a[y]+sqrt(y-x);}
inline ld W_(ll x,ll y) {return a[y]-a[x]+sqrt(y-x);}

inline void DP(ll l,ll r,ll kl,ll kr) {
ll mid=(l+r)>>1,k=kl;
for(ll i=kl;i<=kr&&i<=mid;i++) {if(W(i,mid)>W(k,mid)) k=i;}
f[mid]=W(k,mid);
if(l<mid) DP(l,mid-1,kl,k);if(r>mid) DP(mid+1,r,k,kr);
}

inline void DP_(ll l,ll r,ll kl,ll kr) {
ll mid=(l+r+1)>>1,k=kr;
for(ll i=kr;i>=kl&&i>=mid;i--) {if(W_(mid,i)>W_(mid,k)) k=i;}
f_[mid]=W_(mid,k);
if(l<mid) DP_(l,mid-1,kl,k);if(r>mid) DP_(mid+1,r,k,kr);
}

int main() {

n=read();
for(ll i=1;i<=n;i++) {a[i]=read();}

DP(1,n,1,n);DP_(1,n,1,n);

for(ll i=1;i<=n;i++) {writeln(ceil(max(f[i],f_[i])));}

return 0;
}