二分查找模板题--简单多次二分查询
AcWing 789. 数的范围
给定一个按照升序排列的长度为 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
1
2
3
4
5
输出样例:
3 4
5 5
-1 -1
#include <iostream> #include <algorithm> #include <cstring> using namespace std; const int N = 1e5 + 10; int n, q; int arr[N]; bool check1(int num, int target) { return num < target; } bool check2(int num, int target) { return num <= target; } int binary1( int arr[], int len, int target) { int l = -1; int r = len; while (l + 1 != r ) { //l+1!=r 是l+1<r 的子集 int mid = (r + l) / 2; //((r-1)>>1)+l; if (check1(arr[mid], target)) l = mid; else r = mid; } // 1 2 3 5 5 5 5 6 7 8 if (arr[r] == target) return r; else return -1; } int binary2( int arr[], int len, int target) { int l = -1; int r = len; while (l + 1 != r ) { //l+1!=r 是l+1<r 的子集 int mid = (r + l) / 2; if (check2(arr[mid], target)) l = mid; else r = mid; } // 1 2 3 5 5 5 5 6 7 8 if (arr[l] == target) return l; else return -1; } int main() { cin >> n; //n个数 cin >> q; //q次查询 for (int i = 0; i < n; i++) cin >> arr[i]; while (q--) { int target; cin >> target; int po1 = binary1(arr, n, target);
// 第一个优化:这里可以优化 if(po1=-1){ cout<<"-1 -1"<<endl; continue;} int po2 = binary2(arr, n, target); cout << po1 << " " << po2 << endl; } }
//第二个优化就是我们把check函数里面的判断条件直接写在binary的if条件里
//因为写在check里面还存在函数调用,也是会消耗时间的
/*#include <algorithm> #include <iostream> using namespace std; int n; int m; const int N=1e6+10; typedef long long LL; int a[N]; int main () { cin>>n>>m; for(int i=0;i<n;i++) {cin>>a[i]; } for(int i=0;i<m;i++) {int h; cin>>h; if(a[lower_bound(a,a+n,h)-a]==h) cout<<lower_bound(a,a+n,h)-a+1<<" "; else cout<<"-1 "; } return 0; //c++内的库函数 }*/ #include <iostream> #include <algorithm> #include <cstring> using namespace std; const int N = 1e6 + 10; int arr[N]; int n, q; int binary_search(int arr[], int len, int target) { int l = 0; int r = len + 1; while (l + 1 < r) { int mid = (l + r) / 2; if (arr[mid] < target) l = mid; else r = mid; /* code */ } if (arr[r] == target) return r; else return -1; } int main() { cin >> n; //n个数 cin >> q; //q次查询 for (int i = 1; i <= n; i++) cin >> arr[i]; while (q--) { int target; cin >> target; int po1 = binary_search(arr, n, target); cout << po1 << " "; } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!