二分查找
整数二分
1、用途
快速查询目标值
2、原理
对于有序序列(a[l:r]),每次选取区间中点与目标值比较,若相等则返回目标值,不等则缩小搜索区间。
3、复杂度
(O(logn))
4、模板
//精确查找
function <int(int)> check = [&](int mid) {};
int l, r, ans = -1;
while (l <= r)
{
int mid = l + r >> 1, t = check(mid);
if (!t)
{
ans = mid; break;
}
else
{
if (t > 0) r = mid - 1;
else l = mid + 1;
}
}
//满足某条件的最大值
function <bool(int)> check = [&](int mid) {};
int l, r, ans = l;
while (l <= r)
{
int mid = l + r >> 1;
if (check(mid)) ans = mid, l = mid + 1;
else r = mid - 1;
}
//满足某条件的最小值
function <bool(int)> check = [&](int mid) {};
int l, r, ans = l;
while (l <= r)
{
int mid = l + r >> 1;
if (check(mid)) ans = mid, r = mid - 1;
else l = mid + 1;
}
5、备注
①边界情况非常多,建议背模板。
②往往用于最大值最小/最小值最大类问题上
浮点二分
1、用途
快速查询目标值
2、原理
对于区间([l,r]),每次选取区间中点与目标值比较,若相等则返回目标值,不等则缩小搜索区间。
3、复杂度
(O(logn))
4、模板
//满足某条件的最大值
const double eps = 1e-8;
function <bool(double)> check = [&](double mid) {};
double l, r, ans = l;
while (r - l > eps)
{
double mid = l + (r - l) / 2;
if (check(mid)) ans = mid, l = mid;
else r = mid;
}
//满足某条件的最小值
const double eps = 1e-8;
function <bool(double)> check = [&](double mid) {};
double l, r, ans = l;
while (r - l > eps)
{
double mid = l + (r - l) / 2;
if (check(mid)) ans = mid, r = mid;
else l = mid;
}
例题
暂空