整数二分的本质不是单调性,有单调性可以用二分,无单调性也可以用二分。
二分的本质是以某个位置为划分,前面的满足满足某种性质(BLUE),而后面的满足另外一种性质(RED)。
所以根据查找的是蓝色的划分点还是红色的划分点,整数二分诞生了两种模板。
二分模板;
//伪代码
int binsearch1(int l,int r){
while(l<r){
int mid=l+r+1>>1;
if(checkB(mid)){ //如果满足 则下一个查找[mid,r]
l=mid;
}
else{
r=mid-1;//下一个查找 [l,mid-1]
}
}
return l;
}
int binsearch(int l,int r){
while(l<r){
int mid=l+r>>1;
if(checkR(mid)){// [l,mid]
r=mid;
}
else{
l=mid+1;// [mid+1,r]
}
}
}
因为要保证了l和r属于不同的性质范围之内,所以第一种checkB满足BLUE(mid满足BLUE),l=mid,第二种checkR满足RED(mid满足RED)r=mid。
要注意的是第一种情况mid=l+r+1>>1; 因为,计算机除法是向下取整,若l=3,r=4 checkB满足,(l+r)/2还是3,就陷入了死循环。
ACwing789就满足这种情况(799题解没有按照模板思路走,可以配合本文看一看) 。