题目:兔崽小孩
预备知识:
stl中的二分查找函数:
upper_bound(ForwardIter first, ForwardIter last, const _Tp& val)返回一个非递减序列[first, last)中第一个大于val的位置,返回值为指针,ForwardIter first为数组元素首地址,ForwardIter last为数组元素尾地址的后一个地址。
lower_bound(ForwardIter first, ForwardIter last,const _Tp& val)返回一个非递减序列[first, last)中的第一个大于等于值val的位置。
binary_search( first, last, value ,(cmp) )在已排序的[first,last) 前闭后开 区间中寻找元素value,若存在就返回true,若不存在则返回false 。
先用一个d[i]数组存放每一段休息时长,对d数组进行排序,用d数组的前缀和sum[i]存放前i段休息时长,然后对d数组二分查找,找到单段休息时长大于k的数组下标后直接用公式(休息时长=最大时长-前i-1段的时长-剩余段数*k)求出叉同学的睡觉时长。
这题用cin,cout居然wa了,于是改用scanf和printf。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <string>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn = 1e6 + 10;
int n, q;
int d[maxn];//每段休息时长
ll sum[maxn];//前i段休息时长
int main()
{
scanf("%d %d", &n, &q);
int x, temp;
scanf("%d", &x);
for (int i = 1; i < n; i++) {
scanf("%d", &temp);
d[i] = temp - x;//每段休息时长存入d数组(不考虑入睡时长)
x = temp;
}
sort(d + 1, d + n);
for (int i = 1; i < n; i++) {
sum[i] = sum[i - 1] + d[i];//求前缀和
}
while (q--) {
int k, p;
scanf("%d %d", &k, &p);
int i = upper_bound(d + 1, d + n, k) - d;//二分查找
ll ans = sum[n - 1] - sum[i - 1] - (n - i) * k;//休息时长=最大时长-前i-1段的时长-剩余段数*k
if (ans >= p) printf("Yes\n");
else printf("No\n");
}
return 0;
}