解析注释在对应代码
如果查找不到x,lower_bound(ll x)返回值和upper_bound(ll x)返回值相同 既从左到右第一个大于x的数的下标
思路
①判断循环结束条件
②判断left ,right是否要进行左移右移
③判断最后一次二分后x的位置(存在x)时
//设查找的数为x
//x 属于 [lower,upper)
//二分:每次砍掉一半无用区间,但不砍掉可能存在的答案, 可以自己动手演算一遍,体会过程
int lower(ll x){
//左闭 找区间最左x的数组下标
int left = 0,right = n-1;//数组从下标0开始储存
int middle = (left + right)>>1;
while(left <= right){
// ①left == right 时才能取到right 所以要‘=’
//由①:②这样最后一次二分开始前一定是left == right == middle(这个条件可以推出下面)
if(num[middle]<x) //由①:对任何可能的数据都要使left > right(循环退出) 所以要left right 值都要偏移
left = middle+1; //由②:(如果有x) 不断靠近区间最左x 最后一次二分后x的下标恰好为middle + 1
else right = middle-1;//由②:(如果有x,求最左所以>=x都要左移) 最后一次二分后num[middle] == x;left = middle
middle = (left + right)>>1;
}
return left ;//如果有X一定在left
}
代码思想与上个相同
upper_bound(ll x){
//右开 求从左到右大于x的第一个数
int left = 0,right = n - 1;//数组下标n*n不存数
int middle = (left + right)>>1;
while(left <= right){
//最后一次二分开始前 left == right == middle
if(num[middle]<=x)
left = middle + 1;//右移
else right = middle-1;//左移
middle = (left + right)>>1;
}
return left;//如果有X一定在left
}