二分&lower_bound( )和upper_bound( )
目录
一. 二分
二. lower_bound( )和upper_bound( )
==========================================================
一. 二分
模板一(整数大于等于给定数的第一个数)
int solve(int l, int r)
{
while (l < r)
{
int mid = l + r >> 1;
if (check(mid))
r = mid;
else
l = mid + 1;
}
return l;
}
模板二(整数小于等于给定数的最后一个数)
int solve(int l, int r)
{
while (l < r)
{
int mid = l + r + 1 >> 1;
if (check(mid))
l = mid;
else
r = mid - 1;
}
return l;
}
模板三(实数)
double eps = 1e(-(k+2))//k是所要求的精度
double solve(double l, double r)
{
while(r-l > eps)
{
double mid = (l+r) / 2;
if(check(mid))
r = mid;
else
l = mid;
}
return l;
}
// 也可以直接循环100次,让结果稳定在某个值
double solve(double l, double r)
{
for(int k = 1; k <= 100; k++)
{
double mid = (l+r) / 2;
if(check(mid))
r = mid;
else
l = mid;
}
return l;
}
========================================================
一. 数组从小到大排序
1.lower_bound( begin,end,node):从数组的begin位置到end-1位置二分查找第一个大于或等于node的数字,找到返回该数字的地址,找不到就返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
2.upper_bound( begin,end,node):从数组的begin位置到end-1位置二分查找第一个大于node的数字,找到返回该数字的地址,找不到就返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
二.数组从大到小排序
1.lower_bound( begin,end,node,greater< type >() ):从数组的begin位置到end-1位置二分查找第一个小于或等于node的数字,找到返回该数字的地址,找不到就返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
2.upper_bound( begin,end,node,greater< type >() ):从数组的begin位置到end-1位置二分查找第一个小于node的数字,找到返回该数字的地址,找不到就返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
测试代码
int cmp(int a,int b)
{
return a > b;
}
int main(){
int node[6] = {1,3,5,7,15,66};
sort(num,num+6); //按从小到大排序
int pos1 = lower_bound(num,num+6,7) - num; //返回数组中第一个大于或等于被查数的值
int pos2 = upper_bound(num,num+6,7) - num; //返回数组中第一个大于被查数的值
cout << pos1 << " " << num[pos1] << endl;
cout << pos2 << " " << num[pos2] << endl;
sort(num,num+6,cmd); //按从大到小排序
int pos3 = lower_bound(num,num+6,7,greater<int>()) - num; //返回数组中第一个小于或等于被查数的值
int pos4 = upper_bound(num,num+6,7,greater<int>()) - num; //返回数组中第一个小于被查数的值
cout << pos3 << " " << num[pos3] << endl;
cout << pos4 << " " << num[pos4] << endl;
return 0;
}