“整数二分”悟道:破万千模板乱象,守两套核心纲常

​✅ 网上的“整数二分”模板纷繁杂乱,常常令人无所适从。究其根源,是大量资料把同一种思想下的不同写法混杂罗列,徒增迷惑。二分的内核其实十分纯粹:只要区间具备二段性,就取中点判定,舍弃不可能包含答案的一半,不断收敛范围。

✅ 所有二分问题,核心目标只有两类:
(1)模板A:找“第一个满足条件”的位置(××××√√√√√ → lower_bound)
特点:满足条件 → 保留 mid,ri=mid,不满足条件 → mid 以及左边全部扔掉,le=mid+1。

//目标:找到区间里【第一个满足check(mid)为true】的位置
int le=1,ri=n;
while(le<ri) {
    int mid=(le+ri)/2; //向下取整
    if(check(mid)) ri=mid; //mid满足条件,答案有可能就是mid,右边界缩到mid
    else le=mid+1; //mid不满足,答案一定在mid右边,mid舍弃
}
//循环结束le==ri,就是第一个满足条件的位置

(2)模板B:找“最后一个满足条件”的位置(√√√√√×××× → upper_bound)
特点:满足条件 → 保留 mid,le=mid,不满足条件 → mid 以及右边全部扔掉,ri=mid-1。

//目标:找到区间里【最后一个满足check(mid)为true】的位置
int le=1,ri=n;
while(le<ri) {
    int mid=(le+ri+1)/2; //向上取整,防止相邻死循环
    if(check(mid)) le=mid; //mid满足条件,答案有可能就是mid,左边界拉到mid
    else ri=mid-1; //mid不满足,答案一定在mid左边,mid舍弃
}
//循环结束le==ri,就是最后一个满足条件的位置

这两个“整数二分”模板,所有整数二分,全部都能归进去。别的五花八门的写法,都是变体,不用学。网上 while(le<ri) 和 while(le<=ri) 不是两套互相独立的玄学写法,只是不同编码习惯。建议固定只用 while(le<ri) 这套框架,逻辑统一,降低记忆和出错成本。

✅ 以后写整数二分,先问两个问题:
(1)要找第一个满足,还是最后一个满足?(选A模板还是选B模板)。
(2)check(mid) 满足条件是什么?(自己写 >=、<=、>、< 等可行性判断)。

---------------------------------------------------------------------

✅ 浮点数二分完全是另一个逻辑,简单很多。

//浮点数二分,求根、实数答案
double le=0, ri=1e9;
while(ri-le>1e-6) { //循环结束条件由精度决定
    double mid=(le+ri)/2;
    if(check(mid)) ri=mid;
    else le=mid;
}

(1)与整数二分不同,浮点数二分无需处理边界问题(如 ±1),直接赋值即可。
(2)浮点数二分需设定终止条件(如 while(ri-le>=1e-6) ),通常比题目要求精度高 2 位。过高可能导致死循环,过低则精度不足。
(3)浮点数二分代码模板(数据类型必须使用 double 而非 int,避免计算溢出或精度丢失)。
 

 

​

posted @ 2026-10-29 18:25  Triwa  阅读(5)  评论(0)    收藏  举报