[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; }
|