版权声明:原创,未经作者允许禁止转载 https://blog.csdn.net/Mr_wuyongcong/article/details/89575493
正题
题目大意:https://www.luogu.org/problemnew/show/P3575
题目大意
一个环,上面有若干个点,若干个询问
。
表示上一个降落点和下一个降落点距离不能超过
,然后求至少要降落多少次(起点可以任意)
解题思路
首先明显环形
,然后断环成链,复制一份放到后面,预处理距离前缀和数组
。
然后考虑贪心设
数组,定义
表示
这段范围的降落次数,然后优先飞最远。也就是
是
的最前的降落地点。因为
满足单调性,所以就可以
的预处理出来(或者在
的时候处理)。然后首先显然
然后因为计算上了
,所以要从
开始也就是
然后当
时就是答案了。
#include<cstdio>
#include<algorithm>
#define ll long long
using namespace std;
const ll N=2000100;
ll n,t,imp;
ll sum[N],dp[N],last[N];
void get_answer(ll l){
if(l<imp){
printf("NIE\n");
return;
}
for(ll i=n+1,j=1;i<=2*n;i++){
while(sum[i]-sum[j]>l) j++;
dp[i]=dp[j]+1;
last[i]=last[j];
if(i-last[i]>=n)
{
printf("%lld\n",dp[i]);
return;
}
}
}
int main()
{
scanf("%lld%lld",&n,&t);
for(ll i=1;i<=n;i++){
last[i]=i;
scanf("%lld",&sum[i]);
imp=max(imp,sum[i]);
sum[i+n]=sum[i];
sum[i]+=sum[i-1];
}
for(ll i=n+1;i<=2*n;i++)
sum[i]+=sum[i-1];
for(ll i=1;i<=t;i++){
ll l;scanf("%lld",&l);
get_answer(l);
}
}