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

文章目录

二分全套模板

整数二分分两类:闭区间[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 奶牛晒衣服 - 洛谷

相关推荐
evans在进步21 分钟前
LeetCode 189 轮转数组:三次反转为什么能实现右旋?
数据结构·算法·leetcode
豆沙沙包?24 分钟前
函数重载/类和对象(P14-P60)
前端·算法
艾莉丝努力练剑25 分钟前
【AI大模型接入SDK】DeepSeek API 基础概述
c++·人工智能·学习·ai·面试·deepseek
lingchen190635 分钟前
用MATLAB r2010b和r2016b求解微分方程组
开发语言·算法·matlab
ZiLing35 分钟前
2026 ROS 2 Lyrical C++ 入门(一):rclcpp、QoS、colcon 与 CMake 踩坑指南
c++
OPEN-F1 小时前
C++进阶教程:类与对象深入
java·开发语言·c++
彷徨而立1 小时前
【C++11】内存模型的逻辑时序关系 happens‑before
c++
无定义_1 小时前
Dijkstra——单源最短路径
算法·图论
weixin_307779131 小时前
AI生成代码的隐患与治理:人工审查流程及提示词驱动的修复策略
开发语言·人工智能·算法