Description
Young gardener didn’t visit his garden for a long time, and now it’s not very pleasant there: n caterpillars have appeared on the ground.
Kirill decided to use this opportunity to have some fun and organized a competition — “caterpillar crawl-race.”
At Kirill’s command all caterpillars start crawling from the ground to the top of a tree. But they get tired pretty fast. After crawling ti cm i-th caterpillar needs to rest for ti minutes. During that time it slides down a bit. Crawling speed of a caterpillar is 1 cm/minute, sliding speed — also 1 cm/minute.
Kirill is very much interested to find out how high on the tree is the leading caterpillar at different moments in time.
Input
First line contains one integer n — the number of caterpillars (1 ≤ n ≤ 106).
Second line contains n integers ti — characteristics of caterpillars ( 1≤ti≤109 ).
In the third line there is a number q — number of moments in time, which Kirill finds interesting ( 1≤q≤106 ).
Remaining q lines contain one query from Kirill each. A query is described by xi — number of minutes since the start of the competition ( 1≤xi≤106 ).
Output
For every query print in a separate line one integer, that describes how high is the highest caterpillar at the given moment of time.
题意
给定 n 只毛毛虫,及 n 个数 ti 。对于每只毛毛虫,它们均从 0 时刻以高度 0 向上攀爬,以 1 cm/min 的速度上爬 ti 分钟,再以 1cm/min 的速度下滑 ti 分钟,再以 1 cm/min 的速度上爬 ti 分钟,如此往复。
之后有 q 个询问,每个询问输入一个 x ,问对每个询问给出 n 只毛毛虫在 x 时刻最高的那只毛毛虫的高度。
分析
此题可进行暴力的预处理。
由于询问的 x 最大为 106 ,因此只需预处理出 [1,106] 区间每个时刻的最高高度。
首先可以确定对于毛毛虫 i , ti,3ti,5ti,... 时刻它必定处在最高点,因此暴力处理每只毛毛虫在 ti,3ti,5ti,... 时刻的高度计为 ti ,始终求最大值保存在 ans[ x ] 。
对于其余时刻,可视作最高点向两边的扩展,作二维坐标即斜率为 1
或 -1
。正反向分别扫描,ans[ x ] = max(ans[x], ans[x-1] -1) , ans[ x ] = max(ans[x], ans[x+1] - 1)。
需要注意的是,对于 106 时刻这个截止点,必须额外处理,否则可能在边界出错。
此处不得不提及神奇的 ios::sync_with_stdio(0);
否则会被卡时间。
代码
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6;
int n, q, t[N+10], ans[N+10];
void deal()
{
for(int i=1, j;i<=n;++i)
{
if(t[i] == t[i-1]) continue;
for(j=t[i];j<=N;j+=2*t[i])
if(t[i] > ans[j]) ans[j] = t[i];
ans[N] = max(ans[N], t[i] - (j-N));
}
for(int i=1;i<=N;++i) ans[i] = max(ans[i],ans[i-1]-1);
for(int i=N;i;--i) ans[i] = max(ans[i],ans[i+1]-1);
}
int main()
{
ios::sync_with_stdio(0);
cin>>n;
for(int i=1;i<=n;i++)
cin>>t[i];
sort(t+1, t+n+1);
deal();
cin>>q;
for(int i=1,x;i<=q;i++)
{
cin>>x;
cout<<ans[x]<<endl;
}
}