Конечно, двоичный поиск - это общий алгоритм, который к сортированным данным легко применить. Однако, он может оказаться не самым эффективным, если пытаться учитывть какие то конкретные особенности ваших данных и вариантов использования вашего алгоритма.
Например, если у вас кординаты находятся в каком то небольшом интервале (условно, от 0 до 1000), то можно заранее выделить память под массив и получить константный алгоритм, пример
var data = new[] {
new []{0, 2},
new []{2, 4},
new []{5, 6},
new []{17, 19},
new []{21, 30},
new []{32, 90},
new []{96, 124},
new []{125, 900},
};
var points = Enumerable.Repeat(-1, 1000).ToArray();
for(int i=0; i<data.Length; i++)
for (int j = data[i][0]; j < data[i][1]; j++)
points[j] = i;
Console.WriteLine(points[25]);
Console.WriteLine(points[20]);
Выисление индекса в этом случае тривиальное и очень быстрое. Однако, на таких числах (1000 точек) на практике алгоритм покажет прирост скорости если количество вызовов кода будет большим. Условно, если у вас N точек в интервале, подготовка варианта с массивом займет N и поиск будет константой, при этом двоичный поиск будет Log(N), вроде очевидно, что N+1>log(N) (при N=1000 это будет 1001 > 10, то есть бинарный поиск в 10 раз быстрее). Добавим количество запросов сюда, получим
N + 1*K = K*Log(N)
Чтобы понять, со скольки запросов массив будет обгонять двоичный поиск, решим уравнение
K = N / (Log(N) - 1)
N=1000, то получаем примерно K=10. Конечно, это очень неточно, прямо скажем, сильно очень не точно, но я надеюсь, идея понятная - количество запорсов должно линейно расти (или быстрее, чем линейно) от количества точек, чтобы алгоритм с массивом оставался эффективным. Вот как выглядит зависимость

То есть, условно, на массиве из 40000 точек надо выполнить как минимум 3000-4000 тысячи запросов, чтобы оправдать время построения массива перед обычным довичным поиском.
Другой вариант данных - это когда у вас нет четкого интервала всех точек, но у вас много малентких интервальчиков, все точки которых в сумме влезают в интервал, например, тот же 1000. То есть у вас могут быть [0, 5), [5000, 5007), [10000, 100010) и так далее, но в сумме у вас точек все равно не более 1000, условно. Тогда можно от массива перейти к хештаблице (он же словарь). Пример:
Получение значения из словаря
private int GetOrDefault(Dictionary<int, int> data, int key, int def)
{
if (data.ContainsKey(key)) return data[key];
return def;
}
тест
var data = new[] {
new []{0, 2},
new []{2, 4},
new []{5, 6},
new []{17, 19},
new []{21, 30},
new []{32, 90},
new []{96, 124},
new []{125, 900},
};
var points = new Dictionary<int, int>();
for (int i = 0; i < data.Length; i++)
for (int j = data[i][0]; j < data[i][1]; j++)
points[j] = i;
Console.WriteLine(GetOrDefault(points, 25, -1));
Console.WriteLine(GetOrDefault(points, 20, -1));
Количество ключей в словаре так и останется небольшим, поиск будет что то типа константы (хоть словарь и чутка медленнй доступа к массиву). Ну и рассуждения про массив применимы и здесь.