P5503 灯塔 题解

决策单调性二分

传送门

数据加强版:P3515

前置知识:二分,决策单调性


首先很容易写出答案式子:

\[ ans_{i}=\max_{j=i}^{n}{(a_{j}-a_{i}+\lceil \sqrt{\left| i-j \right |} \rceil)} \]

先将向上取整符号拆掉,只要在输出时处理就行。

再将绝对值符号拆掉,分 \(j<i\)\(j>i\) 的情况考虑,至于 \(i=j\) 的情况,将 \(ans_{i}\) 初始化为 \(0\) 就行。

我们只考虑 \(j<i\) 的情况,另一种情况将数组反过来跑一遍取最大值就行。

设关于 \(i\) 的函数 \(f_{j}{(i)}=a_{j}+\sqrt{i-j}\),对于不同的 \(j\),函数图像随 \(i\) 的变化大概是这样的:

我们来分析一下这张图:图中曲线即 \(f_{j}{(i)}\) 的函数图像,是上凸包,函数的 \(j\) 就是最低点对应的 \(i\)。对于 \(ans_{i}\),最优决策点是函数图像与直线 \(x=i\) 的最高交点。

\(pos_{i}\)\(ans_{i}\) 的最优决策点对应的 \(j\),可以发现:

对于 \(\forall i'<i\),有 \(pos_{i'}\le pos_{i}\)

对于 \(\forall i'>i\),有 \(pos_{i'}\ge pos_{i}\)

然后就可以整体二分来解决了!\(i\) 的区间关于中点 \(mid\) 二分,对 \(j\) 的区间关于当前 \(ans_{mid}\) 的最优决策点二分,注意找最优决策点时还要满足 \(j<i\)


\(\mathcal{Code}\)

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define db double
#define il inline
#define re register
#define INF 0x3f3f3f3f
#define LINF 0x3f3f3f3f3f3f3f3f
#define F(i,a,b) for(re int (i)=(a);(i)<=(b);(i)++)
#define DF(i,a,b) for(re int (i)=(a);(i)>=(b);(i)--)
#define G(i,u) for(re int (i)=head[u];(i);(i)=nxt[(i)])
inline ll read(){ll x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-48;ch=getchar();}return x*f;}
const int N=100010;
int n;
int a[N];
db ans[N];
il db clac(int i,int j)
{//为了满足决策单调性,保证正确性,计算不能取整 
	return a[j]-a[i]+sqrt(i-j);
}//函数图像是一个个凸包,最优凸包不断向右上方延申,满足决策单调性
il void solve(int li,int ri,int lj,int rj)
{
	if(li>ri) return ;
	int i=(li+ri)>>1,pos=lj;
	F(j,lj,min(i,rj)) if(clac(i,pos)<clac(i,j)) pos=j;
	ans[i]=max(ans[i],clac(i,pos));//取j<i和j>i的最优解
	solve(li,i-1,lj,pos);//满足i-1的决策最优点在i的决策最优点pos的左边
	solve(i+1,ri,pos,rj);//满足i+1的决策最优点在i的决策最优点pos的右边
}
int main()
{
	n=read();
	F(i,1,n) a[i]=read();
	solve(1,n,1,n);//j<i的情况
	reverse(a+1,a+n+1);
	reverse(ans+1,ans+n+1);
	solve(1,n,1,n);//j>i的情况
	reverse(a+1,a+n+1);
	reverse(ans+1,ans+n+1);
	F(i,1,n) printf("%d\n",(int)(ceil(ans[i])));
	return 0;
}
posted @ 2023-10-02 17:28  Mo默Sh笙  阅读(17)  评论(0)    收藏  举报