题目
给定一个按照升序排列的长度为 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
C++ 自定义二分
#include <iostream>
using namespace std;
const int maxn = 1e5 +11;
int n,q,k;
int cnt[maxn];
int my_lower_bound(int a[],int l,int r,int target){
int idx = -1;
while(l <= r){
int mid = (l+r)/2;
if(target < a[mid]) r = mid-1;
if(target == a[mid]){
r = mid-1;
idx = mid; //找到值才标记,会多次更新
}
if(target > a[mid]) l = mid+1;
}
return idx;
}
int my_upper_bound(int a[],int l,int r,int target){
int idx = -1;
while(l <= r){
int mid = (l+r)/2;
if(target < a[mid]) r = mid-1;
if(target == a[mid]){
l = mid+1;
idx = mid; //找到值才标记
}
if(target > a[mid]) l = mid+1;
}
return idx;
}
int main(){
cin >> n >> q;
for(int i = 0; i < n; i++) cin >> cnt[i];
while(q--){
cin >> k;
int idx1 = my_lower_bound(cnt,0,n-1,k);
//并不是真实的upper_bound
int idx2 = my_upper_bound(cnt,0,n-1,k);
if(idx1 == -1) cout << "-1 -1" << endl;
else cout << idx1 << " " << idx2 << endl;
}
}
小数二分
#include <iostream>
using namespace std;
int main(){
double a; cin >> a;
double l = 0, r = a;
while(r-l > 0.000001){
double mid = (l+r)/2;
if(mid*mid > a) r = mid;
else l = mid;
}
cout << l << endl;
return 0;
}