二分
单调序列或单调函数中进行查找
当答案具有单调性室,二分求解
--> 三分求单峰函数极值
注意
终止边界,左右区间取舍开闭情况 整数域
精度问题 实数域
实例代码
整数集合
最终答案在闭区间[l,r]内,循环以l==r结束
while (l<r) {
int mid=(l+r)>>1;
if (a[mid]<=x) l=mid;
else r=mid-1;
}
return a[l];
//在单增序列a中查找>=x数中最小的一个
while (l<r) {
int mid=(l+r+1)>>1;
if (a[mid]<=x) l=mid;
else r=mid-1;
}
return a[l];
//查找<=x中最大的一个
由此得出二分两种形式(整数域)
1.r=mid,l=mid+1,mid=(l+r)>>1//不会取到r
2.l=mid,r=mid-1,mid=(l+r+1)>>1//不会取到l
可以扩大至[1,n+1],[0,n]
而实数域只需要l=mid,r=mid即可
需要注意while (r-l>=精度范围*0.1)
upper_bound
lower_bound
例题
1.洛谷P2678 跳石头 (整数域)
2.洛谷P1024 一元三次方程 (实数域) (注意使用double)
三分
同样要求严格单调性
适用于求单峰函数的极值
设置l,m1,m2,r
m1为1/3处
m2为2/3处
double l=0,r=n;
while (r-l>=精度*0.1) {
double m1=l+(r-l)/3.0,m2=r-(r-l)/3.0;
if(f(m1)<f(m2)) l=m1;
else r=m2;
}
//建议自己画图体验一下
例题 洛谷P4653 整数域 需一定数学技巧