数的范围(二分)

题目要求

给定一个按照升序排列的长度为 n 的整数数组,以及 q个查询。

对于每个查询,返回一个元素 k的起始位置和终止位置(位置从 0 开始计数)。

如果数组中不存在该元素,则返回 -1 -1

输入格式

第一行包含整数 n 和 q,表示数组长度和询问个数。

第二行包含 n 个整数(均在 1∼10000 范围内),表示完整数组。

接下来 q 行,每行包含一个整数 k,表示一个询问元素。

输出格式

共 q 行,每行包含两个整数,表示所求元素的起始位置和终止位置。

如果数组中不存在该元素,则返回 -1 -1

数据范围

1≤n≤100000
1≤q≤10000
1≤k≤10000

输入样例:

6 3
1 2 2 3 3 4
3
4
5

输出样例:

3 4
5 5
-1 -1

实例答案

#include<iostream>
#include<algorithm>
#include<string>
#include<math.h>
 
using namespace std;

const int N = 1e6 + 10;

int arr[N];//arr用来储存数组元素
int n, q;//n为数组的大小,q为要询问的次数
int k;//k为每次询问的值

int left_check(int l, int r)//从左向右找第一个与k相等的坐标
{
    while (l < r)
    {
        int mid = l + r >> 1;
        if (arr[mid] >= k) r = mid;
        else l = mid + 1;
    }
    return l;
}

int right_check(int l, int r)//从右向左找第一个与k相等的坐标
{
    while (l < r)
    {
        int mid = l + r + 1 >> 1;
        if (arr[mid] <= k) l = mid;
        else r = mid - 1;
    }
    return l;
}

int main()
{
    scanf("%d%d", &n, &q);

    for (int i = 0; i < n; i++)
    {
        scanf("%d", &arr[i]);
    }

    while (q--)
    {
        scanf("%d", &k);
        
        int d = left_check(0, n - 1);
        if (arr[d] != k) cout << "-1 -1";//如果不等于k则表示不存在
        else
        {
            cout << d << " ";
            d = right_check(0, n - 1);
            cout << d << endl;
        }
    }
    return 0;
}
posted @ 2021-12-13 20:23  ora12321  阅读(9)  评论(0)    收藏  举报