Изменения

Перейти к: навигация, поиск

Link-Cut Tree

109 байт добавлено, 21:56, 10 июня 2014
Решение задачи в частном случае
* подвешивать голову одного пути к хвосту другого.
Если бы не последние две операции, то можно было бы применить [[Дерево отрезков. Построение|дерево отрезков]], сложив в него вершины в том порядке в котором они идут в пути. Но непонятно, как сливать или разрезать деревья отрезков. Если использовать какие-нибудь сливаемые деревья, то <tex>\mathrm{link}</tex> и <tex>\mathrm{cut}</tex> реализуются просто, осталось научиться искать минимум и прибавлять константу на пути. Для этого, как и в деревьях отрезков, будем хранить дополнительные значения в вершинах.
В качестве сливаемых деревьев выберем [[Splay-дерево|splay-деревья]], в которых ключи выбираются равными глубине вершины.
Тогда операции <tex>\mathrm{cut}</tex> будет соответствовать <tex>\mathrm{split}</tex>.
<tex>\mathrm{link(path1, path2)}</tex> соединяет голову первого пути с хвостом второго. Используем функцию <tex>\mathrm{merge(path2, path1)}</tex>, которая вызовет <tex>\mathrm{splay}</tex> от хвоста второго пути и сделает первый путь правым ребенком корня <tex>\mathrm{path2}</tex>, то есть теперь <tex>\mathrm{path1}</tex> находится ниже, чем <tex>\mathrm{path2}</tex>.
Чтобы прибавлять заданное число на пути от вершины до корня, будем в каждой вершине хранить величину <tex>\Delta w</tex>, которая равна разнице между весом вершины и весом её родителя. Для корня это значение равно весу самого корня. Поэтому вес вершины определятся следующим образом:
<tex>w(u) = \displaystyle \sum_v^{} \Delta w(v)</tex>, где v — все предки вершины u.
При прибавлении <tex>\alpha</tex> на пути от вершины <tex>v</tex> до корня, сначала вызывается <tex>\mathrm{splay(v)}</tex>, после чего в левом поддереве находятся вершины, которые лежат на пути к корню. Затем надо прибавить <tex>\alpha</tex> к <tex>\Delta w(v)</tex> и, чтобы сохранить веса вершин, которые находятся ниже в пути, вычесть <tex>\alpha</tex> от <tex>\Delta w(right(v))</tex>.
[[Файл:Linkcut_weights.png|250px|thumb|right|]]
Для реализации <tex>\min</tex> будем хранить минимум уже для всего поддерева. Чтобы искать минимум от вершины <tex>v</tex>, надо вызвать <tex>\mathrm{splay(v)}</tex> и сравнить её вес с минимумом левого поддерева, в котором теперь находятся все вершины пути кроме <tex>v</tex>. Определим <tex>\Delta \min (v)</tex> таким образом, чтобы сохранялся следующий инвариант: <tex>\min (v) = \Delta \min (v) + w(v) </tex>. Пусть <tex>l</tex> и <tex>r</tex> дети <tex>v</tex>, тогда
<tex>\min (v) = \min \{w(v), \min(l), \min(r)\}</tex>
234
правки

Навигация