二分算法
一.类型
- 查找某一有序序列中的某一元素的具体位置
- 查找出某一有序序列中某一元素第一次出现的位置
- 求单调函数零点
- 最大化最小值(例题见 D - Aggressive cows )
- 最小化最大值
- 最大化平均值
二.STL中提供的二分方法
1.头文件: #include< algorithm >
2.对于从小到大排序好的整型数组a[n],假设有a[5]={0,2,3,3,5},对于要查找的整型数val,有
1)int i=lower_bound(a,a+n,val)-a;
其中i返回值为数组中元素值大于等于val的第一个下标,相应地,如果数组中所有元素的值都小于val,则返回值为数组最后一个元素下标的下一个下标(另外一种说法是:i的返回值为val可以插入a数组的最前的位置)。
val=2,i=1;
val=3,i=2;
val=6,i=5;
- int i=upper_bound(a,a+n,val)-a;
其中i返回值为数组中元素值大于val的第一个下标,相应地,如果数组中所有元素的值都小于等于val,则返回值为数组最后一个元素下标的下一个下标(另外一种说法是:i的返回值为val可以插入a数组的最后的位置)。
val=2,i=2;
val=3,i=4;
val=6,i=5;
三.二分模板
int r,l,mid;//a[]为升序排列
r= ;
l= ;
while(l<=r)
{
mid=(r+l)>>1;//或mid=(r+l)/2
if(a[mid]==x)
{
tdtal++;
}
else if(a[mid]>x)
{
r=mid-1;
}
else if(a[mid]<x)
{
l=mid+1;
}
}
四.要点及突破点
-
找有序序列(即二分的对象)
- 乱序的数组排序后
- 一段区间的答案(如最大值)随区间的长度增大而增大
- 在一段区间中找符合题意的最大值(或最小值),那么这段区间即为有序序列
-
判断当前值是否符合题意
- 这个需要结合具体题目
- 一般要写一个函数来判断