一.整数二分的本质:
给定一个区间,并在上面定义了一个性质,使得区间一段满足(红色区间),另一段不满足(区间)
如图:
而二分即找到中间两个边界点。
二. 题目实例
已运行通过:
#include<iostream>
using namespace std;
const int N = 100010;
int q[N];
int m,n,mid;
int main(){
scanf("%d%d",&n,&m);
for(int i = 0;i < n;i++) scanf("%d",&q[i]);
while(m--){
int x;
scanf("%d",&x);
int l = 0,r = n - 1;
while(l < r){
mid = l+r >> 1;
if(q[mid]>= x) r = mid ;//第一次x在mid的左边时
else l = mid + 1;
}
if(q[l] != x) cout << "-1 -1" << endl;
else{
cout << l << ' ';
int l = 0,r = n-1;
while(l < r){
mid = l + r + 1 >> 1;
if(q[mid] <= x) l = mid;
else r = mid-1;
}
cout << l << endl;
}
}
return 0;
}
三. 一些细节问题
- 当更新方式为
l = mid 或r = mid - 1
时,mid = l + r + 1 >> 1
当该区间l = r - 1
时(即区间只有一个整数)若 mid = l + r >> 1 = l(向下取整)
,与l = mid
形成死循环(mid将一直等于l,while死循环)
不同于另一种l = mid -1, r = mid
的更新方式,这里是r = mid,因此不会造成死循环。
补充:
呜呜自己瞎画的图