OK, I see where you're going with this.
Lucene does this with very large bit fields.
Say your possible range of numbers goes from 1 to 64, each of these numbers corresponds to the bit in that position on a 64 bit int. (No 1 is bit 0, No 2 is bit 1).
If you add a number to a range, you switch on that bit (in your example you'd switch on bits 0 through 4 and 19 through 29).
Now to check a range of numbers, you create another 64 bit int with that range of bits switched on, and perform a bitwise And (&) on the two bit fields. The 1 bits in the result is the overlapping range.
For more numbers than 64, just scale up the number of bits (possibly by working with arrays or lists of integers)
Hope this helps :)
Update: Scalability
Lets say you're working on 64 bit architecture and you can AND 64 bit integers in a single operation. Ideally you'd use 64 bit ints.
Now, lets say your possible range of numbers runs from 1 to 64,000, for this you need 1000 64 bit ints.
Now lets look at a couple use cases
I want to check the range of 70 - 80.
To do this we don't need another 1000 ints for the check, just one int, and we know we're checking it against the 2nd element in our array.
I want to check the range of 2000 - 10,000
Again, we only need one int, calculate it's position in the array 31st (I think) and set the bits accordingly and compare. Then you iterate through the list until you hit 10,000 (position 156?), comparing along the way, and building you're list of integers to return.
Update 2: That's not O(1)
Depending of the size of the range to check, you can implement this as O(1)
However using this algorithm the general case is still O(n)