二分模版

90 阅读1分钟

我们在二分的时候需要满足步骤:

一.先确定一个区间,使得目标值一定在一个区间内。

二.q找一个性质,性质需要满足以下两点:

1.性质需要满足二段性,即一个点前半段不满足·要求,后半段满足要求。

2.答案是2段性的分界点。

二分的2个模板

第一种,找大于等于X的最小数

比如对于下面这种情况(X小于mid) :

image.png 那么[X,mid]之间肯定全部都是大于X的值,那么答案(大于等于X的第一个数),肯定在[X,mid]之间,所以我们需要缩小右区间,r=midr=mid

为什么不是r=mid-1呢?因为[X,mid]都是可能包含答案的。

那么假设X大于mid呢?如图:

image.png

如图所示,答案(大于等于x的第一个数)肯定在[X,R]之间。

那么左半边肯定没有我们的答案,我们需要缩小左端点:

l=mid+1

为什么是L=mid+1,而不是L=mid呢? 因为mid肯定不包括答案。

对于这种情况,我们的模板就是

while(l<r)
{
  int mid=l+r>1;
  if(check()) r=mid;
  else l=mid+1;
}



第二种情况,找小于等于X的第一个数

image.png 如上图所示,答案(小于等于X的第一个数) 肯定在左半区间,所以我们需要缩小右端点:

r=mid-1  (因为mid不包括答案)

假设mid<x:

image.png

那么答案肯定在[l,x]之间,所以需要缩小左端点:

l=mid (如图所示,mid可能包含答案)

对于第二种情况,模板如下:

while(l<r)
{
  int mid=l+r+1>>1;
  if(check()) l=mid
  else r=mid-1;
}



板子总结

image.png