Мы всем поддерживаем кайф, нам кайф ломают кругом
DSU
Семейство непересекающихся множеств
Дано множество \(E = \{x_i\colon i < n\}\) — Универсум.
В каждый момент времени существует разбиение
такое, что
Находит применение в решении задач
Будем хранить компоненты связанности в виде деревьев. На них определим операцию \(\mathrm{GetRoot}(x)\), возвращающую корень дерева, в котором содержится \(x\).
Для каждой вершины поставим в соответствие её родителя \(\mathrm{Parent}(x)\). Для корней родитель не определён (\(\varnothing\)).
Как выбрать корень нового дерева?
Для каждого дерева определим ранг как высота этого дерева минус 1
Тогда в качестве нового корня выберем дерево с большим рангом.
Если \(r(X) < r(Y)\), тогда \(r(X \cup Y) = r(X)\), следовательно \(w(X \cup Y) \geqslant 2^{r(X, Y)}\).
Если \(r(X) = r(Y)\), тогда
Можно не запоминать ранги, используя вместо них рандомизацию. Получим рандомизированный логарифм.
После применения операции \(\mathrm{GetRoot}(x)\) выполним операцию \(\mathrm{Squash}(x, root)\).
def squash(x, root):
p = x.parent
if p != root:
x.parent = root
return squash(p, root)
Храниться только в корнях.
Важно задать правила по которым будет определяться статистика после слияния.
Лес с двумя операциями:
Массив с индексами родителей.
Для корней можно хранить отрицательное число, в котором кодировать ранг или статистику.
Также можно добавлять новые элементы.