题目链接:I-兔崽小孩_2022牛客寒假算法基础集训营5 (nowcoder.com)
题目:叉同学虽然是wf爷,但平时傻愣愣的,游戏也玩不过九峰,经常被九峰取笑。有一次叉同学熬夜看球并在凌晨四点半和五点半连发两条说说,被早起水群的刘教主看到了,骂他道:"兔崽子,你这是玩通宵啊,不要命啦"。从此叉同学凌晨发说说总是慎之又慎,避免被骂。
假设叉同学入睡需要k分钟,且他必须醒着才能发说说,刘教主早上醒来后发现他肯定没睡够p分钟就会骂他,叉同学想知道自己是否会被骂。
输入描述:
第一行一个正整数n,q,n,q,n,q,表示说说条数和询问个数 第二行nnn个正整数t1,t2,...,tn,t_1,t_2,...,t_n,t1,t2,...,tn,表示nnn条说说的时间,保证ti<ti+1(i<n)t_i<t_{i+1}(i < n)ti<ti+1(i<n) 接下来qqq行每行一次询问,每行两个正整数k,p,k,p,k,p,表示叉同学的入睡需要时间和刘教主认为叉同学需要的睡眠时间
输出描述:
对于每次询问,如果叉同学不会被骂则输出一行"Yes",否则输出一行"No"(不包括双引号)
示例1
输入
复制5 2 1 2 5 9 10 3 1 3 2
5 2 1 2 5 9 10 3 1 3 2
输出
复制Yes No
Yes No
说明
叉同学入睡需要3分钟,所以只可能在第3第4两条说说之间的4分钟间隔睡1分钟
备注:
n,q≤106n,q \leq 10^6n,q≤106 ti≤109t_i \leq 10^9ti≤109 k,p≤109k,p \leq 10^9k,p≤109 叉同学发第一条说说之前和发完最后一条说说之后视为一直醒着
思路:先将发说说的间隔时间存下来,按照降序排序,做个前缀和,然后二分找到第一个小于等于k的位置,然后看前缀和-区间长度*k是否符合。
lower_bound(ans,ans+cnt,k,greater<int>()) (返回ans数组中第一个小于等于k的位置)
代码:
#include<bits/stdc++.h>
using namespace std;
#define int long long
int a[1000005],ans[1000005],sum[1000005];
bool cmp(int x,int y){ return x>y;}
signed main()
{//1716,1250964
int n,q,cnt=0;
scanf("%lld %lld",&n,&q);
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
}
for(int i=2;i<=n;i++){
ans[cnt++]=a[i]-a[i-1];
}
sort(ans,ans+cnt,cmp);
sum[0]=ans[0];
for(int i=1;i<cnt;i++) sum[i]=(ans[i]+sum[i-1]);
while(q--){
int k,p,res=0,i=0;
scanf("%lld %lld",&k,&p);
i=lower_bound(ans,ans+cnt,k,greater<int>())-ans-1;
res=sum[i]-(i+1)*k;
if(res>=p) printf("Yes\n");
else printf("No\n");
}
}