数的范围

数的范围

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

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

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

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

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

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

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

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

数据范围
1n100000

1q10000

1k10000
输入样例:
6 3
1 2 2 3 3 4
3
4
5
输出样例:
3 4
5 5
-1 -1

思路

  1. 整数二分
  2. lower_bound,upper_bound

Code

1. 整数二分

点击查看代码
#include<iostream>
using namespace std;
int n,q;
const int N = 1e5 + 10;
int a[N];
int main(){
	cin >> n >> q;
	for(int i = 0; i < n; i ++)cin >> a[i];
	
	while(q --){
		int x;
		cin >> x;
		int l = 0,r = n - 1;
		while(l < r){
			int mid = l + r >> 1;
			if(a[mid] >= x)r = mid;
			else l = mid + 1;
		}
		if(a[l] == x){
			cout << l << " ";
			r = n - 1;
			while(l < r){
				int mid = l + r + 1>> 1;		//l = mid时l+r+1>>1
				if(a[mid] <= x)l = mid;
				else r = mid - 1;
			}
			cout << r << endl;
		}
		else cout << "-1 -1" << endl;
	}
}

2. lower_bound,upper_bound

点击查看代码
#include<iostream>
using namespace std;
const int N = 1e5 + 10;
int a[N];

int main(){
	int n,q;
	cin >> n >> q;
	for(int i = 0; i < n; i ++)cin >> a[i];
	while(q --){
		int op;
		cin >> op;
		int l = lower_bound(a,a+n,op) - a,r = upper_bound(a,a+n,op) - a - 1;
		if(a[l] == op && a[r] == op)cout << l << " " << r << endl;
		else cout << "-1 -1"<< endl;
	}
	return 0;
}

注意:

  1. lower_bound( begin,end,num):从数组的begin位置到end-1(左闭右开)位置二分查找第一个大于或等于num的数字,找到返回该数字的地址不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
  2. upper_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
posted @   Keith-  阅读(115)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示