二分查找模板总共有两个
版本一
将区间分为 [ l , m i d ] [l,mid] [l,mid], [ m i d + 1 , r ] [mid+1, r] [mid+1,r]时,代码如下
while (l < r)
{
int mid = l + r >> 1;
if (a[mid] >= x)
{
r = mid;
}
else
{
l = mid + 1;
}
}
版本二
将区间分为 [ l , m i d − 1 ] [l,mid-1] [l,mid−1], [ m i d , r ] [mid, r] [mid,r]时,代码如下
while (l < r)
{
int mid = l + r + 1 >> 1;
if (a[mid] <= x)
{
l = mid;
}
else
{
r = mid - 1;
}
}
对于版本一,区间会一直向左划分,直到找到最小的
i
n
d
e
x
index
index使得
a
[
i
n
d
e
x
]
>
=
x
a[index]>=x
a[index]>=x,若
a
[
l
]
!
=
x
a[l]!=x
a[l]!=x,则无解。
对于版本二,区间会一直向右划分,直到找到最大的
i
n
d
e
x
index
index使得
a
[
i
n
d
e
x
]
<
=
x
a[index]<=x
a[index]<=x,若
a
[
l
]
!
=
x
a[l]!=x
a[l]!=x,则无解。
一个题目,如果一个区间具有单调性质,那么一定可以二分,但是如果说这道题目没有单调性质,而是具有某种区间性质的话,我们同样可以使用二分。 ——yxc总
下面看一道AcWing的题目AcWing789.数的范围