P5503 [JSOI2016] 灯塔

P5503 [JSOI2016] 灯塔

不难发现 \(\sqrt{|i-j|}\) 只有 \(\sqrt{n}\)
种取值,对于每一个取值我们只需要满足在该取值下 \(h\) 的最大值满足 $$h_j \le h_i+p-\sqrt {|i-j|}$$ 就好了。

本来本蒟蒻是想写一个st表去暴力维护的,可是大佬和我说这题的决策具有单调性,然后我的st表就这样被优化掉了

Code:

#include<bits/stdc++.h>
#define int long long 
const int N=1e5+5;
using namespace std;
int n;
int h[N],pre[N],suf[N];
void work()
{
	cin>>n;
	for(int i=1ll;i<=n;i++)
	{
		scanf("%lld",&h[i]);
	}
	pre[1]=h[1];
	for(int i=2ll;i<=n;i++)
	{
		pre[i]=max(pre[i-1ll],h[i]);
		for(int j=0ll;j*j<=(i-1ll);j++)
		{
			pre[i]=max(pre[i],h[(i-1ll)-j*j]+j+1ll);
		}
	}
	suf[n]=h[n];
	for(int i=n-1ll;i;i--)
	{
		suf[i]=max(suf[i+1ll],h[i]);
		for(int j=0ll;j*j<=n-(i+1ll);j++)
		{
			suf[i]=max(suf[i],h[(i+1ll)+j*j]+j+1ll);
		}
	}
	for(int i=1ll;i<=n;i++)
	{
		printf("%lld\n",max(pre[i],suf[i])-h[i]);
	}
}
#undef int
int main()
{
	//freopen("P5503.in","r",stdin);
	//freopen("P5503.out","w",stdout);
	work();
	return 0;
	
}
posted @ 2024-12-06 12:08  liuboom  阅读(11)  评论(0)    收藏  举报