题目 给定一个按照升序排列的长度为 $n$ 的整数数组,以及 $q$ 个查询。 对于每个查询,返回一个元素 $k$ 的起始位置和终止位置(位置从 $0$ 开始计数)。 如果数组中不存在该元素,
题目
给定一个按照升序排列的长度为 $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
思路
二分模板
- 找左边界
while (l < r)
{
int mid = (l + r) >> 1;
if (k <= f[mid]) r = mid;
else l = mid + 1;
}
- 找右边界
int l = 0, r = n - 1;
while (l < r)
{
int mid = (l + r + 1) >> 1; // +1是为了防止越界
if (k >= f[mid]) l = mid;
else r = mid - 1;
}
代码
#include <iostream>
using namespace std;
const int N = 100010;
int n, q, k, f[N];
void bs()
{
int l = 0, r = n - 1;
while (l < r)
{
int mid = (l + r) >> 1;
if (k <= f[mid]) r = mid;
else l = mid + 1;
}
if (f[l] != k) cout << "-1 -1" << endl;
else
{
cout << l << " ";
int l = 0, r = n - 1;
while (l < r)
{
int mid = (l + r + 1) >> 1;
if (k >= f[mid]) l = mid;
else r = mid - 1;
}
cout << l << endl;
}
}
int main()
{
cin >> n >> q;
for (int i = 0; i < n; i ++ ) scanf("%d", &f[i]);
while (q -- )
{
cin >> k;
bs();
}
return 0;
}