题目地址:
https://www.acwing.com/problem/content/791/
给定一个长
n
n
n的升序数组
A
A
A,以及
q
q
q个查询,每次查询问某个整数
k
k
k在
A
A
A中出现的起始位置和终止位置。如果不存在则输出-1 -1
。下标从
0
0
0开始。
输入格式:
第一行包含整数
n
n
n和
q
q
q,表示数组长度和询问个数。第二行包含
n
n
n个整数(均在
1
∼
10000
1\sim 10000
1∼10000范围内),表示完整数组。接下来
q
q
q行,每行包含一个整数
k
k
k,表示一个询问元素。
输出格式:
共
q
q
q行,每行包含两个整数,表示所求元素的起始位置和终止位置。如果数组中不存在该元素,则输出-1 -1
。
数据范围:
1
≤
n
≤
100000
1\le n\le 100000
1≤n≤100000
1
≤
q
≤
10000
1\le q\le 10000
1≤q≤10000
1
≤
k
≤
10000
1\le k\le 10000
1≤k≤10000
对于每次询问,用二分查找找出第一次和最后一次出现的位置。代码如下:
#include <iostream>
using namespace std;
const int N = 100010;
int n, q, k;
int a[N];
int main() {
scanf("%d%d", &n, &q);
for (int i = 0; i < n; i++) scanf("%d", &a[i]);
int x, y;
while (q--) {
cin >> k;
int l = 0, r = n - 1;
while (l < r) {
int m = l + (r - l >> 1);
if (a[m] >= k) r = m;
else l = m + 1;
}
if (a[l] != k) {
puts("-1 -1");
continue;
}
x = l;
l = 0, r = n - 1;
while (l < r) {
int m = l + (r - l + 1 >> 1);
if (a[m] <= k) l = m;
else r = m - 1;
}
y = l;
printf("%d %d\n", x, y);
}
}
每次查询时间复杂度 O ( log n ) O(\log n) O(logn),空间 O ( 1 ) O(1) O(1)。