P3515 [POI2011] Lightning Conductor 题解
核心代码共十行。
思路
显然可以把左侧和右侧分开处理来拆掉绝对值,下文中都考虑
鉴于
考虑一个比较容易想到的做法:
我们可以从左往右扫
考虑能不能不重算整个最大值。可以注意到,左侧每个点
所以我们根本就没必要重算最大值,直接把那几个通过断点的点的新贡献
左右各跑一遍即可在每个
这样就可以把时间复杂度降到
下面是非常简短的代码。谷上吸了氧可以跑到 650ms 左右,LOJ 上吸氧可以跑进 500ms。
int n;
int h[N];
int maxn;
int ans[N];
int main(){
#ifdef zjh
freopen("hack.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
ios::sync_with_stdio(false);
cin>>n;
fr1(i,1,n) cin>>h[i];
maxn=0;
fr2(i,n,1){
ans[i]=maxn;
for(int j=0;j*j<=n-i;j++) maxn=max(maxn,h[i+j*j]+j+1);
}
maxn=0;
fr1(i,1,n){
ans[i]=max(ans[i],maxn);
for(int j=0;j*j<=i-1;j++) maxn=max(maxn,h[i-j*j]+j+1);
}
fr1(i,1,n) cout<<max(ans[i]-h[i],0)<<'\n';
ET;
}