给定一个按照升序排列的长度为 nn 的整数数组,以及 qq 个查询。
对于每个查询,返回一个元素 kk 的起始位置和终止位置(位置从 00 开始计数)。
如果数组中不存在该元素,则返回 -1 -1
。
输入格式
第一行包含整数 nn 和 qq,表示数组长度和询问个数。
第二行包含 nn 个整数(均在 1∼100001∼10000 范围内),表示完整数组。
接下来 qq 行,每行包含一个整数 kk,表示一个询问元素。
输出格式
共 qq 行,每行包含两个整数,表示所求元素的起始位置和终止位置。
如果数组中不存在该元素,则返回 -1 -1
。
数据范围
1≤n≤1000001≤n≤100000
1≤q≤100001≤q≤10000
1≤k≤100001≤k≤10000
输入样例:
6 3
1 2 2 3 3 4
3
4
5
输出样例:
3 4
5 5
-1 -1
代码如下:
#include<iostream>
#include<cstdio>
#include<stdio.h>
#include <cstring>
#include <algorithm>
#include <queue>
#include<cstring>
#pragma warning(disable:4996)
using namespace std;
const int MAXN = 1e6 + 5;
long long n, c;
long long a[MAXN];
// 记录答案法(容易理解)
long long FindLow(long long num)
{
// 二分查找过程
int left = 0, right = n - 1;
int ans = -1;
while (left <= right) {
int mid = (left + right) >> 1;
if (a[mid] >= num) {
if (num == a[mid]) { // 记录答案
ans = mid;
}
right = mid - 1;
} else {
left = mid + 1;
}
}
if (ans == -1) return -1;
else return ans;
}
// 不记录答案法
long long FindHigh(long long num)
{
// 至于下面的一些来避免死循环的操作可以自己用样例来模拟一便就懂其中的原理了
int left = 0, right = n - 1;
while (left < right) { // 此处如果left加上=条件也会造成死循环
int mid = (left + right + 1) >> 1; // 此处的+1操作是用来解决死循环问题的
if (a[mid] <= num) {
left = mid;
} else {
right = mid - 1;
}
}
if (a[left] == num) return left;
else return -1;
}
int main() {
cin >> n >> c;
for (int i = 0; i < n; i++) {
cin >> a[i];
}
sort(a, a + n);
int tmpcinn;
for (int j = 0; j < c; j++) {
cin >> tmpcinn;
cout << FindLow(tmpcinn) << " ";
cout << FindHigh(tmpcinn) << endl;
}
return 0;
}