二分思想
如果我们要在一个有序数列中搜索一个数字的时候,
使用暴力搜索的时间复杂度为O(n),这个时候我们可以
采取二分查找这种算法,每一次搜索都能将搜索范围缩小一半
其时间复杂度为O(logn)
模板
算法也需要背公式,而这里的公式就是模板
(笔者是从Acwing当中学习而来,感兴趣原理的朋友可以自行去学习)
二分模板
while(l<r){
int mid=l+r+1>>1;
if(check(mid))l=mid;
else r=mid-1;
}
----------------------
while(l<r){
int mid=l+r>>1;
if(check(mid))r=mid;
else l=mid+1;
}
数的范围

这道题是二分查找的模板题,直接应用二分模板即可
//这里是引入了一些常用的头文件,宏定义是因为该死的编译器不让直接用scanf
#define _CRT_SECURE_NO_WARNINGS 1
#include<algorithm>
#include<iostream>
#include<sstream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<string>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#define MAX 0x3f3f3f3f
#define MIN -0x3f3f3f3f
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int N = 1e5 + 10;
int a[N];
int n, q, k;
int main() {
cin >> n >> q;
//读入数据
for (int i = 0; i < n; i++)cin >> a[i];
while (q--) {
cin >> k;
int l = 0, r = n;
//先找起始位置,即mid右侧包括mid的元素都是大于等于k的元素
while (l < r) {
int mid = l + r >> 1;
//目标元素在mid左侧,则收缩右边界
if (a[mid] >= k)r = mid;
else l = mid + 1;
}
if (a[l] != k) {
cout << "-1 -1" << endl;
}
else {
cout << l << " ";
//再找最终位置,即mid左侧都是小于等于k的元素
l = 0, r = n;
while (l < r) {
int mid = l + r + 1 >> 1;
//目标元素在mid右侧,则收缩左边界
if (a[mid] <= k)l = mid;
else r = mid - 1;
}
cout << l << endl;
}
}
return 0;
}
1758

被折叠的 条评论
为什么被折叠?



