Here's a method if the questions in my comment question are affirmative:
p2[l_, arg_] := Module[{a, p, m, vi},
a = Unitize[Append[Differences[l], 2] - 1];
p = Pick[Range@Length@l, a, 1];
m = l[[p]];
vi = Length[p] + 1 - Reverse[Accumulate@Reverse@a];
If[arg === True,
AssociationThread[l -> Transpose[{m[[vi]], p[[vi]]}]],
With[{pp = Pick[vi, l, arg]}, Join[m[[pp]], p[[pp]]]]]];
Usage:
For a single-shot query (say if target list is changing often or between calls):
result=p2[list,key]
where list, key are your list and the element to search. If element not present, returns empty list, else returns two element list of high value and corresponding position.
For multiple calls anticipated against some static list:
(* do *once* per static list *)
myFn=p2[list,True];
(* use returned object for repeated searches on that list *)
result=myFn[key]
Returns same two element list of high and position for valid key, else Missing["KeyAbsent", ...] for an invalid element.
Using
list = Flatten[Range @@@ Partition[Sort@RandomInteger[{1, 50000}, 100], 2]];
to generate test data, this seems to be quite quick for single-shot use, and can build the lookup function quite quickly, which is then of course orders of magnitude faster for multiple searches on a static list.
If your lists are tiny and/or only searched a few times, not worth the complexity, but if not, might save you some processing time.
Update:
For the second part in you comment, here's a q-n-d helper function to do that:
p2h[l_, arg_] :=
Module[{i}, If[MemberQ[l, arg], p2[l, arg], i = Pick[Range@Length@l, UnitStep[l - arg], 1];
If[i == {}, {}, p2[l, l[[i[[1]]]]]]]];
This calls the original function (one-shots) for existing elements, or crafts the appropriate call to the original function for "between" elements.
N.b: This does not take advantage of pre-calculation in the original function, but from your comments it appears lists are not static, so probably irrelevant. The ranges are considered unbounded on left (so calling with any value less that the minimum of the target returns the first maximum) and bounded on the right (so calling with a value greater than any in the list returns the empty list - there is no "...smallest number from range that is greater than selected number").
There's probably a more efficient way to tie these together, don't have time right now. In the future, keep in mind it's best to state the whole problem at once, if possible, versus trickle-changes.