백준 10816 기준

1. lower bound

int lower_idx(int target, int N) {
	int st = 0;
	int en = N;
	while (st < en) {
		int mid = (st+en)/2;
		if (arr[mid] >= target) en = mid;
		else st = mid + 1;
	}
	return st;
}

2. upper bound

int upper_idx(int target, int N) {
	int st = 0;
	int en = N;
	while (st < en) {
		int mid = (st+en)/2;
		if (arr[mid] > target) en = mid;
		else st = mid + 1;
	}
	return st;
}

3. test

#include <bits/stdc++.h>
using namespace std;

int arr[100001];

void log(int st, int en) {
    cout << "arr[" << st << "]: " << arr[st] << " / arr[" << en << "]: " << arr[en] << '\\n';
}

int lower_idx(int t, int N) {
	int st = 0, en = N;

    log(st, en);
    
	while (st < en) {
		int mid = (st+en)/2;
		if (arr[mid] >= t) en = mid;
		else st = mid + 1;

        log(st, en);
	}
	return st;
}

int upper_idx(int t, int N) {
    int st = 0, en = N;

    log(st, en);

    while (st < en) {
        int mid = (st+en)/2;
        if (arr[mid] > t) en = mid;
        else st = mid + 1;

        log(st, en);
    }
    return st;
}

int main() {
    ios_base::sync_with_stdio(0); cin.tie(0);

    int N; cin >> N;
    for (int i=0; i<N; i++) cin >> arr[i];

    sort(arr, arr+N);

    int t = 16;
    lower_idx(t, N);
    cout << "---------------------------\\n";
    upper_idx(t, N);

    return 0;
}

Reference