二分 & 三分
二分查找
多用于dp优化
源码
//自己写的时候推荐把边界放宽一点
while(r-l>1) { //最后一个小于k的位置
int mid=l+r>>1;
if(a[mid]<x) l=mid;
else r=mid-1;
}
if(a[r]<x) l=r;
STL库函数
注意以下返回的都是指针
#include<algorithm>
upper_bound(a+1,a+n+1,k) //第一个大于k的位置
lower_bound(a+1,a+n+1,k) //第一个大于等于k的位置
bool cmp(int x,int k) { //自定义规则,注意k是给定参数,不是a[]的元素
return val[x]<=val[k];
}
lower_bound(a+1,a+n+1,k,cmp) //第一个不符合cmp的位置
upper_bound(a+1,a+n+1,k,cmp) //最后一个符合cmp的位置
细节处理
给定不降序列
1、小于
边界:
二分答案
01分数规划
核心:抽象出 ,求最大值则判大于0,求最小值则判小于0
模型
有一些二元组
设
即
二分
若存在最优答案>=0,则当前二分值偏小。否则,说明偏大。
p.s. 也有除数为连续区间长的,即
例题
例1:[P3199] 输出平均值最小的环的平均值
n<=3000,m<=10000
例2:有带权图G, 对于图中每条边
P3778 [APIO2017] 商旅
先是分数规划,
该环可以分成根据包里的物品分成若干段,分段考虑,对于段
p.s. 想要分层图+SPFA的我像个sb
p.s.s. 这题卡精度,有个答案是
整体二分
三分
细节说明
边界
对于整数下标的三分,可能出现
int l=1,r=MAXN;
while(true) {
int m1=l+(r-l)/3,m2=r-(r-l)/3;
if(l==m1||r==m2) break;
if(Check(m1)<Check(m2)) r=m2;
else l=m1;
}
ans=Check(l);
for(int i=l+1;i<=r;i++) ans=min(ans,Check(i));
不适用情况
答案符合单峰函数,但是变化幅度过小(尤其是整数三分),使得Check(m1)==Check(m2),不知道转移方向 (整数三分事真多)
解决方法
1、一定条件下转换成二分来用
2、去重(不是枚举去重,是找贡献点,因为变化幅度小的贡献点很少)
例:[P1314] 上述两种都适用
[P6619] 构成单峰的是两段单调的曲线,考虑它们分别产生贡献的两段,分别二分找答案即可
首先放到
题意即为求一个时刻
即求一个
即为
两式相减得
令
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】