二分查找知识总结

整数二分:

二分的本质并不是单调性,而是从一半满足一半不满足的区间中找到边界点。

模板题:

数的范围

给定一个按照升序排列的长度为n的整数数组,以及q个查询。

对于每个查询,返回一个元素k的起始位置和终止位置(位置从0开始计数)。

如果数组中不存在该元素,则返回 -1 -1

输入格式

第一行包含整数n和q,表示数组长度和询问个数。

第二行包含n个整数(均在1~10000范围内),表示完整数组。

接下来q行,每行包含一个整数k,表示一个询问元素。

输出格式

共q行,每行包含两个整数,表示所求元素的起始位置和终止位置。

如果数组中不存在该元素,则返回 -1 -1

数据范围

1 <= n <= 100000

1 <= q <= 10000

1 <= k <= 10000

输入样例:

6 3
1 2 2 3 3 4
3
4
5

输出样例:

3 4
5 5
-1 -1

代码模版:

复制代码
 1 #include <iostream>
 2 
 3 using namespace std;
 4 
 5 const int N = 1e5 + 10;
 6 
 7 int n, m;
 8 int q[N];
 9 
10 int main()
11 {
12     scanf("%d%d", &n, &m);
13     for (int i = 0; i < n; i++) scanf("%d", &q[i]);
14     
15     while (m--)
16     {
17         int x;
18         scanf("%d", &x);
19         
20         int l = 0, r = n - 1;
21         while (l < r)
22         {
23             int mid = l + r >> 1;
24             if (q[mid] >= x) r = mid;
25             else l = mid + 1;
26         }
27         
28         if (q[l] != x) cout << "-1 -1" << endl;
29         else
30         {
31             cout << l << ' ';
32             
33             int l = 0, r = n - 1;
34             while (l < r)
35             {
36                 int mid = l + r + 1 >> 1;
37                 if (q[mid] <= x) l = mid;
38                 else r = mid - 1;
39             }
40             
41             cout << l << endl;
42         }
43     }
44 
45     return 0;
46 }

View Code

浮点数二分:

模板题:

数的三次方根

给定一个浮点数n,求它的三次方根。

输入格式

共一行,包含一个浮点数n。

输出格式

共一行,包含一个浮点数,表示问题的解。

注意,结果保留6位小数。

数据范围

-10000 <= n <= 10000

输入样例:

1000.00

输出样例:

10.000000

代码模版:

复制代码
 1 #include <iostream>
 2 
 3 using namespace std;
 4 
 5 int main()
 6 {
 7     double x;
 8     cin >> x;
 9     
10     double l = -10000, r = 10000;
11     while (r - l > 1e-8)
12     {
13         double mid = (l + r) / 2;
14         if (mid * mid * mid >= x) r = mid;
15         else l = mid;
16     }
17     
18     printf("%lf\n", l);
19     
20     return 0;
21 }

View Code