AcWing算法基础1.3

二分

二分分为整数二分和实数二分,其中整数二分模板有两个

模板:

整数二分模板

第一种模板将区间分为[ l , mid ]  和 [ mid + 1, r ]

 1 int bsearch_1(int l, int r)
 2 {
 3     while(l < r)
 4     {
 5         int mid = l + r >> 1;
 6         if(check(mid))  r = mid;  // check为判断 mid 性质
 7         l = mid + 1;
 8     }
 9     return l;
10 }

第二种模板把区间分为[ l , mid - 1] 和 [ mid , r ],需要注意的是,这里算mid时要用 l + r + 1 >> 1; 这里需要加一

 1 int bsearch_2(int l, int r)
 2 {
 3     while(l < r)
 4     {
 5         int mid = l + r + 1>> 1;
 6         if(check(mid))  l = mid; // check判断 mid 的性质
 7         r = mid - 1;
 8     }
 9     return l;
10 },

计算 mid 时 +1,是因为防止陷入死循环,用第二种模板会有种情况使循环陷入死循环,例如某次更新后区间变成 [x1, x2 ] ,如果我们计算 mid 时不 +1,l + r >> 1为向下取整,所以我们计算的 mid 始终是 l ,此时 l < r 恒成立如果 if () 条件成立 l = mid,至此循环将一直进行下去,陷入死循环

实数二分就简单多了,因为我们不用考虑边界情况,直接二分即可

 1 double bsearch_3(double l, double r)
 2 {
 3     const double eps = 1e-6; //eps表示精度,取决于题目对精度的要求
 4     while(r - l > eps)
 5     {
 6         double mid = (l + r) / 2;
 7         if(check(mid))  r = mid;
 8         else l = mid;
 9     }
10     return l;
11 }
原文地址:https://www.cnblogs.com/chuyds/p/10948458.html