Use binary search - for the input interval [i, j], find the index of the smallest integer that is greater than i, find the index of the largest integer that is less than j, and then return the distance between them.
ssize_t bin_search_first_larger(int arr[], size_t arr_sz, int val) {
ssize_t l = -1;
ssize_t r = arr_sz;
while (l+1 != r) {
ssize_t m = l+(r-l)/2;
if (arr[m] < val) {
l = m;
} else {
r = m;
}
}
return r;
}
ssize_t bin_search_last_smaller(int arr[], size_t arr_sz, int val) {
ssize_t l = -1;
ssize_t r = arr_sz;
while (l+1 != r) {
ssize_t m = l+(r-l)/2;
if (arr[m] <= val) {
l = m;
} else {
r = m;
}
}
return l;
}
ssize_t values_in(int arr[], size_t arr_sz, int x, int y) {
ssize_t i = bin_search_first_larger(arr, arr_sz, x);
ssize_t j = bin_search_last_smaller(arr, arr_sz, y);
return j-i+1;
}
The binary search code is adapted from Jon Bentley Programming Pearls (which is well worth reading), which shows how a binary search can be modified to return either the first occurrence or the last occurrence of a value in a sorted array with duplicates (instead of returning an arbitrary occurrence of a duplicate values). The process is similar to your use case, the difference is subtle.
, , arr[-1] - , arr[N] - ( N - ), , , .
O(log(N)), N - , (?) - .
, , , ( , y , , x , , x y , ), , , , , .