5.数的范围

 

 二分的本质并不是单调性。

有单调性一定可以二分,但是可以二分的题目不一定有单调性。

我们找一个性质:使得整个区间可以被划分为两个左右区间,一边满足这个性质,一边不满足这个性质,中间没有交点。二分就可以寻找这个性质的边界。

上红下绿。

 

每次二分时都选择答案所在的区间进行操作,每一次都保证区间里一定有答案,当区间长度是1的时候,答案一定就是它。

注意:二分的时候一定是有解的,可能题目无解,不过二分一定有解。

我们定义的这个性质一定有边界,二分一定可以把边界二分出来。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int N = 100010;
 4 int a[N];
 5 int main () {
 6     int n, q;
 7     cin >> n >> q;
 8     for (int i = 0; i < n; i++) {
 9         cin >> a[i];
10     }
11     while (q--) {
12         int x;
13         cin >> x;
14         int l = 0, r = n - 1;
15         while (l < r) {
16             int mid = l + r >> 1;
17             if (a[mid] >= x) {
18                 r = mid;
19             } else {
20                 l = mid + 1;
21             }
22         }
23         //如果我们这个序列中不存在x的话,那么我们二分出来的是个啥东西呢 
24         //二分出来的是从左往右最前面的那个满足>=x的那个数 
25         if (a[l] != x) {
26             cout << "-1 -1" << endl;
27         } else {
28             cout << l << " "; //此处输出l或r都是一样的,因为当这个while循环结束的时候,l=r 
29             int l = 0, r = n - 1;
30             while (l < r) {
31                 int mid = l + r + 1 >> 1;
32                 if (a[mid] <= x) {
33                     l = mid;
34                 } else {
35                     r = mid - 1;
36                 }
37             }
38             cout << l << endl;
39         }
40     }
41     return 0;
42 }

猜你喜欢

转载自www.cnblogs.com/fx1998/p/12804738.html