#include <iostream>
using namespace std;
const int N = 1e5+5;
int a[N];
// @return [l,r) 中 第一个大于等于 x 的值的下标 (a[N] 升序)
int lower_bound(int l, int r, int x) {
while (l < r) {
int mid = (l+r)>>1;
if (a[mid] >= x) r = mid;
else l = mid+1;
}
return l; // if l == r(传入) 则cannot find the result
}
// @return [l,r) 中 第一个大于 x 的值的下标 (a[N] 升序)
int upper_bound(int l, int r, int x) {
while (l < r) {
int mid = (l+r)>>1;
if (a[mid] > x) r = mid;
else l = mid+1;
}
return l; // if l == r(传入) 则 cannot find the result
}
// 上述两例 可以 应用 最小化最大值 升序 左闭右开
// 下述两例 可以 应用 最大化最小值 降序 左开右闭
// @return (l,r] 中 最后一个小于等于 x 的值的下标 (a[N] 升序)
int last_less_equal(int l, int r, int x) {
while (l < r) {
int mid = (l+r+1)>>1;
if (a[mid] <= x) l = mid;
else r = mid-1;
}
return l; // if l == l(传入) 则 cannot find the result
}
// @return (l,r] 中 最后一个小于等于 x 的值的下标 (a[N] 升序)
int last_less(int l, int r, int x) {
while (l < r) {
int mid = (l+r+1)>>1;
if (a[mid] < x) l = mid;
else r = mid-1;
}
return l; // if l == l (传入) 则 cannnot find the result
}
int main() {
int k = 1;
for (int i=0; i<=4; i++) {
a[i] = k++;
}
cout << upper_bound(0, 5, 5) << endl; // 左闭右开
cout << last_less_equal(-1, 4, 1) << endl; // 左开右闭
return 0;
}