[JSOI2016]灯塔

链接:https://www.luogu.com.cn/problem/P5503

题目描述:对于每一个i,求出hjhi+|ij|的最大值。

题解:令第i个数的答案为dpi,打表可以发现h具有决策单调性。这一类决策单调性可以采用整体二分的方式求得决策点范围,由于决策点可能相同,所以不能先取整。

#include<iostream>
#include<cmath>
#include<cstdio>
using namespace std;
double dp[1000001],dp2[1000001],f[1000001];
long long h[1000001],n,p[1000001],p2[1000001];
void solve(int l,int r,int L,int R)
{
	int mid=(l+r)/2;
	for (int i=R;i>=L;--i)
		if (i<mid&&h[i]+f[mid-i]>dp[mid])
		{
			dp[mid]=h[i]+f[mid-i];
			p[mid]=i;
		}
	if (l==r)
		return; 
	solve(l,mid,L,p[mid]);
	solve(mid+1,r,p[mid],R);
	return;
}
void solve2(int l,int r,int L,int R)
{
	int mid=(l+r)/2;
	for (int i=R;i>=L;--i)
		if (i>mid&&h[i]+f[i-mid]>dp2[mid])
		{
			dp2[mid]=h[i]+f[i-mid];
			p2[mid]=i;
		}
	if (l==r)
		return;
	solve2(l,mid,L,p2[mid]);
	solve2(mid+1,r,p2[mid],R);
	return;
}
int main()
{
	cin>>n;
	for (int i=1;i<=n;++i)
	{ 
		cin>>h[i];
		dp[i]=-1e18;
	}
	for (int i=1;i<=n;++i)
		f[i]=sqrt(i);
	solve(1,n,1,n);
	solve2(1,n,1,n);
	for (int i=1;i<=n;++i)
		cout<<(int)(ceil(max(max(dp[i],dp2[i])-h[i],(double)(0))))<<endl;
	return 0;
}
posted @   zhouhuanyi  阅读(19)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示
主题色彩