时间复杂度:O(logN)
用法:在一个左闭右开(a,b] 的有序区间里进行二分查找,需要查找的值由第三个参数给出。
条件:使用这两个函数注意要有序
对于upper_bound来说,返回的是被查序列中第一个大于查找值的指针,也就是返回指向 被查值 > 查找值 的最小指针,lower_bound则是返回的是被查序列中第一个大于等于查找值的指针,也就是返回指向 被查值 >= 查找值 的最小指针。
不过除此之外,这两个函数还分别有一个重载函数,可以接受第四个参数。如果第四个参数传入greater<Type>()
,其中Type改成对应类型,那么upper_bound则返回指向 被查值<查找值 的最小指针,lower_bound则返回指向 被查值 <= 查找值 的最小指针。
注意写成lower_bound(a, a+n, x)-a,是从0开始计数;(必须-数组首地址才能得到第一个>=x的数的下标)
lower_bound(a+1, a+n+1, x)-a,是从1开始计数。
注意:如果用上述两个函数三个参数的那种形式,记得左闭右开的区间要为非递减的顺序,
如果给第四个参数传入greater<Type>()
,则区间为非递增的顺序。
#include <iostream> #include <algorithm> using namespace std; //返回一个非递减序列 [1,n] 中的第一个 >= x 的位置 int main() { int a[50]; int n, x, ans; cin >> n >> x; for(int i=1; i<=n; i++) { cin >> a[i]; } ans = lower_bound(a+1, a+n+1, x) - a; cout << ans << endl; return 0; }
#include <iostream> #include <algorithm> using namespace std; //返回一个非递减序列 [1,n] 中的第一个 <= x 的位置 int main() { int a[50]; int n, x, ans; cin >> n >> x; for(int i=0; i<n; i++) { cin >> a[i]; } ans = lower_bound(a, a+n, x, greater<int>()) - a; cout << ans << endl; return 0; } /* 5 3 5 4 3 2 1 2 */
#include <iostream> #include <algorithm> using namespace std; //返回一个非递减序列 [1,n] 中的第一个 > x 的位置 int main() { int a[50]; int n, x, ans; cin >> n >> x; for(int i=0; i<n; i++) { cin >> a[i]; } ans = upper_bound(a, a+n, x) - a; cout << ans << endl; return 0; } /* 5 3 1 2 3 4 5 3 */
#include <iostream> #include <algorithm> using namespace std; //返回一个非递减序列 [1,n] 中的第一个 < x 的位置 int main() { int a[50]; int n, x, ans; cin >> n >> x; for(int i=0; i<n; i++) { cin >> a[i]; } ans = upper_bound(a, a+n, x, greater<int>()) - a; cout << ans << endl; return 0; } /* 5 3 5 4 3 2 1 3 */
当一个序列里面某个数多次出现:
upper_bound(a,a+n,x) - lower_bound(a,a+n,x) 得到的是值为x的个数
if(x==2) 1 2 2 2 3 ——> upper_bound(a,a+n,x) - lower_bound(a,a+n,x) = 3
#include <iostream> #include <algorithm> using namespace std; //返回一个非递减序列 [1,n] 中的第一个 <= x 的位置 int main() { int a[50]; int n, x, ans = 0; cin >> n >> x; for(int i=0; i<n; i++) { cin >> a[i]; } ans += upper_bound(a, a+n, x) - lower_bound(a, a+n, x) ; cout << ans << endl; return 0; } /* 5 2 1 2 2 2 3 3 */