789. 数的范围
题意
给定一个按照升序排列的长度为n的整数数组,以及 q 个查询。
对于每个查询,返回一个元素k的起始位置和终止位置 (位置从0开始计数) 。
如果数组中不存在该元素,则返回“-1 -1”。
思路
对于这样一个数组 {1 2 2 3 3 4} ,查询2,我们要输出下标 1 和 2 ,也就是该数的左边界和右边界。
如果我们只写一个不同的二分找到任意一个 2 的位置,然后往左右遍历找到边界,可能也能过,但会被一些极端的数据卡掉,比如 {1 2 2 ··· 2 2 3} 这种。
所以需要用到寻找左右边界的二分。
当然,也并不是说不用二分就不能做,对于这个有序数组,我们完全可以记录每个数字出现的第一个位置,以及每个数字出现的次数,然后这题也就迎刃而解了。
代码
使用库函数 low_bound 和 upper_bound
#include<bits/stdc++.h>
using namespace std;
int a[100005];
int main()
{
int n,q,k;
cin >> n >> q;
for(int i = 0; i < n; ++i)
cin >> a[i];
while(q--){
cin >> k;
int l = lower_bound(a,a+n,k)-a;
printf("%d ",a[l