1

Тема: задача на дерево отрезков

Манхэттенское расстояние
На плоскости дано N различных  точек.  Расстоянием между точками (x1,  y1)  и (x2,  y2) будем
считать |x1 - x2| + |y1 - y2|. Для каждой точки требуется найти одну из ближайших к ней точек.
Формат входных данных
Первая строка входного  файла  содержит целое число N  (1 <  N <= 100000).  Следующие  N строк
содержат   по   два   числа   —   координаты  точек.   Координаты   —   целые  числа,   по   модулю   не
превышающие 10000. Числа в строках разделены пробелами.
Формат выходных данных
Выходной файл должен содержать N целых чисел, разделенных пробелом: i-е число  есть номер
одной из точек, ближайших  к  i-й. Точки  нумеруются  в том  порядке, в  котором они  даны во
входном файле, начиная с единицы.

2 Отредактировано KADR (2010-04-22 15:41:15)

Re: задача на дерево отрезков

Для каждой точки найдем ближайшую к ней которая лежит левее ее либо имеет ту же икс координату, но лежит ниже. Очевидно что дальше для каждой точки легко найти ближайшую среди всех остальных.
Отсортируем точки лексикографически (т.е. по икс координате, а при равных иксах по игрекам). Пусть на i-м шагу мы рассматриваем точку с координатами (x,y). Найдем для нее ближайшую точку (x',y').
|x-x'|+|y-y'| - минимально
x>=x', поэтому первый модуль можно убрать
x-x'+|y-y'| - минимально

Теперь рассмотрим 2 случая:

1) y'<=y
Тогда второй модуль раскроется со знаком + и получим
x-x'+y-y'=(x+y)-(x'+y') - минимально
Значит, нам нужно максимизировать (x'+y').
Заведем дерево отрезков по игрекам, где для каждого игрека будем хранить максимальное значение (x'+y') среди точек с таким игреком, которые мы уже добавили в дерево. Тогда чтобы максимизировать (x'+y') надо просто найти максимум среди точек с игреками [-10000,y].

2) y'>y
Второй модуль раскроется со знаком минус. Тогда имеем:
x-x'+y'-y=(x-y)-(x'-y') - минимально
Опять таки, нам нужно максимизировать (x'-y'). Заведем второе дерево отрезков и будем хранить в нем величины (x'-y'). Отвечать на запросы будем так же как и в первом случае.

Теперь просто из двух найденных точек выберем ту, которая ближе. Далее обновим оба дерева отрезков (добавим текущую точку) и перейдем к следующей. Сложность O(NlogR+NlogN), где R - макс. y координата. Если бы координаты могли быть большими, то имело бы смысл сделать сжатие координат и тогда сложность была бы просто O(NlogN).

3

Re: задача на дерево отрезков

Спасибо, интересно.

Ужать координаты только для такой задачи не получится... Но в этом случае вместо дерева отрезков можно, например, декартово дерево взять с этого сайта.

Потестировать алгоритм можно на http://www.spoj.pl/problems/GANNHAT/

4

Re: задача на дерево отрезков

Почему не получится? Можно строить дерево отрезков по сжатым координатам, а минимум брать по старым.

5

Re: задача на дерево отрезков

Согласен smile

6

Re: задача на дерево отрезков

Казалось бы, можно просто перебрать, с каким знаком раскроется каждый модуль в манхеттенской метрике, и при каждом варианте (их 4) отсортировать все точки по этому критерию, и попроверять две соседние. Т.е. 4 сортировки и прохода.

7

Re: задача на дерево отрезков

О каком именно критерии идет речь?

8

Re: задача на дерево отрезков

Ну один из четырёх:
x+y, -x+y, x-y, -x-y.
Понятно, что для любой точки ближайшая к ней будет и ближайшей в одной из этих четырёх сортировок.

Действительно, берём метрику:
|x1-x2|+|y1-y2| -> min
И пусть модули оба с плюсом раскрылись. Тогда:
x1-x2+y1-y2 = (x1+y1)-(x2+y2) -> min
Это значит, что при таком раскрытии модуля точки 1 и 2 будут соседними в порядке сортировки по x+y.
Повторяя эти рассуждения для 3 других способов раскрытия модулей, как раз и получаем моё утверждение.

9

Re: задача на дерево отрезков

Не совсем понимаю, почему они будут соседними в порядке сортировки. Раз (x1+y1)-(x2+y2) минимально, то наоборот нам выгоднее брать вторую точку с максимальным (x2+y2).

10

Re: задача на дерево отрезков

Рассмотрим, например, тест:
4
4 0
7 6
3 6
1 5

Тут всего 4 точки. Ближайшей точкой к (4,0) будет точка (3,6) с расстоянием до нее 7.
Теперь переберем 4 случая раскрытия модуля, отсортируем массивы и посмотрим, будет ли хоть в одном из них точка (3,6) соседней с (4,0):

1) x+y: (4,0), (1,5), (3,6), (7,6).
2) x-y: (1,5), (3,6), (7,6), (4,0).
3) -x+y: (4,0), (7,6), (3,6), (1,5).
4) -x-y: (7,6), (3,6), (1,5), (4,0).

Как видно, ни разу точки (4,0) и (3,6) не оказываются рядом. Кстати, варианты 3-4 сортировки это просто развернутые задом наперед варианты 1-2.

11

Re: задача на дерево отрезков

Хмм, что этот метод только для наиболее удалённой пары применим?.. Такая задача просто уже встречалась, но там, насколько я помню, была самая удалённая пара точек (и другая метрика, но тоже сумма модулей). Казалось, что для ближайшей пары можно применить те же утверждения, но теперь я уже склоняюсь к обратному smile