From 2ae0310dda17aef59e4dadd5cb575524ceb2f797 Mon Sep 17 00:00:00 2001 From: mrChest228 Date: Wed, 28 Jan 2026 20:42:47 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9F=D1=80=D0=B5=D0=B4=D1=8B=D0=B4=D1=83?= =?UTF-8?q?=D1=89=D0=B8=D0=B9=20=D0=B0=D0=BB=D0=B3=D0=BE=D1=80=D0=B8=D1=82?= =?UTF-8?q?=D0=BC=20Divide-and-conquer=20=D0=BF=D0=BE=20=D0=B7=D0=B0=D0=BF?= =?UTF-8?q?=D1=80=D0=BE=D1=81=D0=B0=D0=BC=20=D0=B1=D1=8B=D0=BB=20=D0=BD?= =?UTF-8?q?=D0=B5=D0=BF=D1=80=D0=B0=D0=B2=D0=B8=D0=BB=D1=8C=D0=BD=D1=8B?= =?UTF-8?q?=D0=BC,=20=D0=B5=D1=89=D1=91=20=D0=B8=20=D0=BF=D0=B5=D1=80?= =?UTF-8?q?=D0=B5=D0=B2=D0=B5=D1=88=D0=B5=D0=BD=D0=BD=D1=8B=D0=BC=20=D0=B2?= =?UTF-8?q?=20=D1=81=D1=82=D0=BE=D1=80=D0=BE=D0=BD=D1=83=20"=D0=BF=D1=80?= =?UTF-8?q?=D0=B0=D0=B2=D0=BE=D0=B9=20=D0=BF=D0=BE=D0=BB=D0=BE=D0=B2=D0=B8?= =?UTF-8?q?=D0=BD=D1=8B=20=D0=B7=D0=B0=D0=BF=D1=80=D0=BE=D1=81=D0=BE=D0=B2?= =?UTF-8?q?".=20=D0=AF=20=D0=B8=20=D0=BC=D0=BE=D0=B9=20=D0=B4=D1=80=D1=83?= =?UTF-8?q?=D0=B3=20=D0=BE=D0=B1=20=D0=BD=D0=B5=D0=B3=D0=BE=20=D1=81=D0=BF?= =?UTF-8?q?=D0=BE=D1=82=D0=BA=D0=BD=D1=83=D0=BB=D0=B8=D1=81=D1=8C,=20?= =?UTF-8?q?=D0=BF=D0=BE=D1=8D=D1=82=D0=BE=D0=BC=D1=83=20=D1=8F=20=D1=80?= =?UTF-8?q?=D0=B5=D1=88=D0=B8=D0=BB=20=D1=83=D0=BB=D1=83=D1=87=D1=88=D0=B8?= =?UTF-8?q?=D1=82=D1=8C=20=D1=81=D1=82=D0=B0=D1=82=D1=8C=D1=8E.=20=D0=9E?= =?UTF-8?q?=D0=BF=D0=B8=D1=81=D0=B0=D0=BB=20=D1=80=D0=B5=D1=88=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20DCP=20=D1=87=D0=B5=D1=80=D0=B5=D0=B7=20=D0=B4?= =?UTF-8?q?=D0=B5=D1=80=D0=B5=D0=B2=D0=BE=20=D0=BE=D1=82=D1=80=D0=B5=D0=B7?= =?UTF-8?q?=D0=BA=D0=BE=D0=B2=20=D0=BF=D0=BE=D0=BD=D1=8F=D1=82=D0=BD=D1=8B?= =?UTF-8?q?=D0=BC=20=D1=8F=D0=B7=D1=8B=D0=BA=D0=BE=D0=BC=20=D0=B8=20=D0=BD?= =?UTF-8?q?=D0=BE=D1=80=D0=BC=D0=B0=D0=BB=D1=8C=D0=BD=D1=8B=D0=BC=20=D0=BF?= =?UTF-8?q?=D1=80=D0=BE=D1=81=D1=82=D1=8B=D0=BC=20=D1=80=D0=B5=D0=BA=D1=83?= =?UTF-8?q?=D1=80=D1=81=D0=B8=D0=B2=D0=BD=D1=8B=D0=BC=20=D0=B0=D0=BB=D0=B3?= =?UTF-8?q?=D0=BE=D1=80=D0=B8=D1=82=D0=BC=D0=BE=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- content/russian/cs/spanning-trees/dcp.md | 28 ++++++++++++------------ 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/content/russian/cs/spanning-trees/dcp.md b/content/russian/cs/spanning-trees/dcp.md index bbbe816d..f7a20cb1 100644 --- a/content/russian/cs/spanning-trees/dcp.md +++ b/content/russian/cs/spanning-trees/dcp.md @@ -1,12 +1,12 @@ --- title: Динамическая связность authors: -- Сергей Слотин -date: 2021-09-25 + - Сергей Слотин +date: 2021-09-25T00:00:00.000Z prerequisites: -- /cs/set-structures/dsu -- /cs/persistent/persistent-array -- /cs/decomposition/rollback + - /cs/set-structures/dsu + - /cs/persistent/persistent-array + - /cs/decomposition/rollback --- В контексте графов, система непересекающихся множеств напрямую решает следующую задачу: @@ -37,17 +37,17 @@ prerequisites: ### Divide-and-conquer по запросам -Давайте вместо корневой эвристики заведем рекурсивную функцию `solve(l, r)`, которая будет отвечать на все запросы с $l$ по $r$, имея СНМ, соответствующий всем ребрам, которые существуют на всем этом промежутке. +Давайте вместо корневой эвристики заведём дерево отрезков, в вершинах которого сохраним все рёбра, существующие целиком на всём отрезке этой вершины и не существующие целиком на отрезке её предка. Таким образом каждое ребро окажется не более чем в $log(n)$ вершинах ДО. -Эта функция будет действовать следующим образом: +Рёбра, имеющие несколько отрезков жизни можно считать разными рёбрами и добавлять в ДО независимо, т. к. эти отрезки не пересекаются, а также их суммарное количество будет не более $n$. -0. Если в промежутке всего один запрос, то найдем ответ на него через СНМ и выйдем. В противном случае: -1. Разделим промежуток времени пополам: `t = (l + r / 2)`. -2. Рекурсивно разрешим левую половину: `solve(l, t)`. -3. Добавим в СНМ те ребра, которые существуют на всей правой половине запросов. -4. Рекурсивно запустимся от правой половины: `solve(t, r)`. -5. Откатим СНМ до изначального состояния. +Чтобы найти ответ, можно пройтись по дереву отрезков такой `dfs(v)`: -Так как мы всегда поддерживаем инвариант «когда мы запускаемся и выходим из рекурсии, СНМ всегда чистый для этого промежутка», алгоритм действительно ответит на все запросы и будет работать за $O(n \log^2 n)$. +0. Добавим в СНМ рёбра из тек. вершины ДО $v$. +1.0. Если отрезок единичной длины, ответим на все его запросы, +1.1. Иначе запустимся в левого, а затем и в правого ребёнка. +2. Откатим все добавленные из тек. вершины $v$ в СНМ рёбра. + +Несложно заметить, что асимптотика алгоритма $O(n \log^2 n)$, потому что каждое из не более $n$ рёбер мы добавим в не более чем $log(n)$ отрезком ДО, в каждый отрезок зайдём ровно по 1 разу и каждое ребро из него добавим в СНМ за $O(log(n))$. Заметим, что мы нигде не использовали ничего конкретно про связность — можно отвечать на любые запросы, поддерживаемые СНМ, например о размерах компонент или числе ребер. Также существуют модификации для других задач, например для нахождения мостов или компонент двусвязности — подробнее можно почитать в [дипломной работе](http://se.math.spbu.ru/SE/diploma/2012/s/Kopeliovich_diploma.pdf) Сергея Копелиовича.