二分模板(整型,浮点型)

文章目录

二分全套模板

整数二分分两类:闭区间[l,r] while(l<=r) 、左闭右开[l,r) while(l<r);浮点数二分固定循环次数 / 判断eps精度。

一.🔍关键词

高频关键词 二分类型
尽可能大的XX 二分答案,求最大可行解(整数模板2 mid+1)
尽可能小的XX 二分答案,求最小可行解(整数模板1)
最大值最小 二分答案,最小的最大值
最小值最大 二分答案,最大的最小值
切成k段、划分k组 二分答案
最少时间、最少代价 二分答案,求最小可行
保留小数,求最大/最小XX 浮点数二分

二.二分使用前提

要么数组有序;要么答案区间上条件单调

三、整数二分模板

查询元素

适用:查找元素是否存在;闭区间找最小/最大可行答案(P1843奶牛晒衣服就是这套)

复制代码
bool check(int x,int l,int r){
	while(l<=r){
   	int mid=l+(r-l)/2;
   	if(a[mid]==x){
   		return true;
	   }else if(a[mid]>x){
	   	r=mid-1;
	   }else{
	   	l=mid+1;
	   }
   }
	return false;
}

闭区间求最小可行解

(找满足条件的最小t,例如晒衣服)

复制代码
//check(mid):mid可行返回true
int l=1,r=max_val;
int ans=r; //ans初始为合法上界
while(l<=r)
{
    int mid=l+(r-l)/2;
    if(check(mid))
    {
        ans=mid;
        r=mid-1; //可行,尝试更小
    }
    else
    {
        l=mid+1; //不可行,放大
    }
}
//ans就是答案

闭区间求最大可行解

复制代码
int l=1,r=max_val;
int ans=0;
while(l<=r)
{
    int mid=l+(r-l)/2;
    if(check(mid))
    {
        ans=mid;
        l=mid+1; //可行,尝试更大
    }
    else
    {
        r=mid-1;
    }
}
//ans为答案

第一个 ≥ x 的位置(lower_bound)

复制代码
int check(int x,int l,int r){
	int flag=-1;
	while(l<=r){
   	int mid=l+(r-l)/2;
   	if(a[mid]>x){
   		r=mid-1;
   		flag=mid;
	   }
	   else{
	   	l=mid+1;
	   }
   }
	return flag;
}

第一个 > x 的位置(upper_bound)

复制代码
int check(int x,int l,int r){
	int flag=-1;
	while(l<=r){
   	int mid=l+(r-l)/2;
   	if(a[mid]>x){
   		r=mid-1;
   		flag=mid;
	   }
	   else{
	   	l=mid+1;
	   }
   }
	return flag;
}

四、浮点数二分模板

(实数二分,比如P1577切绳子)

两种写法:①固定循环次数(推荐,精度稳定,不怕eps调错);②eps判断。

写法1:固定循环100次

循环100次,精度可以达到 10 − 30 10^{-30} 10−30,远超题目要求。

复制代码
double l=0, r=1e9;
//循环100次足够
for(int i=1;i<=100;i++)
{
    double mid = (l + r)/2;
    if(check(mid))
    {
        //看题意:如果可行想要更大,l=mid;想要更小 r=mid
        l=mid;
    }
    else
    {
        r=mid;
    }
}
//输出l或者r
printf("%.2f\n",l);

写法2:eps精度控制

复制代码
const double eps=1e-4; //输出保留2位,eps取1e‑4或1e‑5,比输出精度多2位
double l=0,r=1e9;
while(r - l > eps)
{
    double mid=(l+r)/2;
    if(check(mid))
    {
        l=mid;
    }
    else
    {
        r=mid;
    }
}
printf("%.2f\n",l);

⚠️重点:如果题目要求输出k位小数,eps设置要比输出精度小2个数量级。

例:输出2位小数 → eps=1e‑4;输出6位 → eps=1e‑8。


五.经典例题

二分查找(一) - 计蒜客

二分查找(二) - 计蒜客

二分查找(三) - 计蒜客

P1577 切绳子 - 洛谷

P1824 [USACO05FEB 进击的奶牛 Aggressive Cows G - 洛谷](https://www.luogu.com.cn/problem/P1824)

P1843 奶牛晒衣服 - 洛谷

相关推荐
微尘hjx4 小时前
【ByteTrack 04】多轨迹算法ByteTrack改进点
算法·yolo·目标检测·目标跟踪·bytetrack·ultralytics·车跟踪
dtq04245 小时前
C++小案例 - 日志实战
开发语言·c++
路灯上の马陈6 小时前
二叉树的定义与性质
数据结构·二叉树·树结构·1024程序员节
码匠许师傅6 小时前
【C++三方组件】Qt 概览:桌面 C++ 的事实标准与许可证三轨
开发语言·c++·qt
码匠许师傅7 小时前
【C++三方组件】POCO:跨平台系统编程全家桶
开发语言·c++
小蒋观天下8 小时前
雷击与浪涌防护:前端SPD选型、接地网误区,接地不当反而引入干扰
深度学习·算法·机器学习
Bshaya_9 小时前
红黑树详解:概念、规则与插入实现
数据结构·红黑树·二叉搜索树·平衡树·插入逻辑
WBluuue10 小时前
数据结构与算法:分块(一):块状数组、块状链表
数据结构·c++·算法·链表
路灯上の马陈11 小时前
数据结构-树
数据结构·1024程序员节