If u have oracle 8.1.6 u can use the rank function.

to select top(n)
select emp, salary
from ( select emp_name emp, emp_salary salary,
rank() over (order by emp_salary desc) as rank1
from emp)
where rank1 < 10

replacing rank1 by
rank1 < 20 and rank1 > 10 retrieves the between values.

I have tested it.
I haven't used this is production yet so cannot comment on timing. I use the conventional rownum way as suggested above.

in case there is a a tie, rank will eliminate one so use dense_rank in such cases. I am not sure whether the tie is defined as duplicate in select(same employee same salary) or duplicate in order by ( same salary diff employees).

There are some more cool statistical stuff in 8.1.6 that u might like to check out.