P6473 [NOI Online #2 入门组]未了(民间数据)

题目描述

由于触犯天神,Sisyphus 将要接受惩罚。宙斯命 Sisyphus 推一块巨石上长度为 L 的山坡。Sisyphus 匀速向上推的速度为每年 v 的长度(由于是匀速,故经过 1/2​ 年将能向上推 v/2​ 的长度)。然而,宙斯并不希望 Sisyphus 太快到达山顶。宙斯可以施展 n 个魔法,若宙斯施展第 i 个魔法 (1≤i≤n),则当 Sisyphus 第一次到达位置 a_i 时,他将会同巨石一起滚落下山底,并从头推起。(滚落的时间忽略不计,即可看作第一次到达位置 aia_iai​ 后 Sisyphus 立即从山底重新出发)例如宙斯施用了 a_i=3 和 a_i=5 的两个魔法。Sisyphus 的速度 v=1,山坡的长度 L=6,则他推石上山过程如下:用 3 年走到位置 3。受 a_i=3 的魔法影响,回到了山底出发。再用 3 年走到位置 3,然而因为是第二次到达,a_i=3 的魔法不起作用。用 2 年走到位置 5。受 a_i=5 的魔法影响,回到了山底出发。用 6 年从山底走到了山顶。花费的总时间为 14 年。现在,宙斯有 q 个询问。对于第 i 个询问 t_i​,宙斯想知道,他最少需要施展多少个魔法才能使 Sisyphus 到达山顶所用的年数大于 t_i

输入格式

第一行三个整数 n,L,v 分别表示魔法的种类数,山坡的长度,Sisyphus 的速度。第二行 n 个整数。第 i 个整数 a_i 表示第 i 个魔法作用的位置。(1<i<n)第三行一个整数 q 表示宙斯的询问个数。接下来 q 行每行一个整数,第 i 行的整数 t_i​ 表示宙斯的第 i 个询问。(1<i<n)

输出格式

输出 q 行,每行恰好一个整数,第 i 行的整数对应第 i 个询问的答案。(1≤i≤q)如果宙斯无论如何都不能使 Sisyphus 使用的年数大于 t_i​,请输出 -1。\

输入

3 6 3
3 5 1
4
1
3
4
5

输出

0
1
2
-1

思路

用前缀和求出“石人”走到第i个位置的用时,在线操作,计算开启魔法的最优个数,显然从后往前开最划算。
code:

#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
int n,l,u;
double b[200005];
int a[200005];
bool cmp(int a,int b)
{
 return a>b;
}
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}
    while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
    return x*f;
}
int main()
{
    n=read(),l=read(),u=read();
    for (int i=1;i<=n;i++) a[i]=read();
    sort(a+1,a+n+1,cmp);
    for (int i=1;i<=n;i++) b[i]=b[i-1]+a[i];
    int q=read();
    while (q--)
    {
        long long t=read();
        t=t*u-l;
        if (t<0) puts("0");
        else if (b[n]>t) cout<<upper_bound(b+1,b+n+1,t)-b<<endl;
        else puts("-1");
    }
    return 0;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值