Centroid decomposition — различия между версиями
(→Введение) |
(→Введение) |
||
Строка 17: | Строка 17: | ||
Первая задача решается методом [[Сортировка_слиянием|qevide&conqure (рус. разделяй и властвуй)]] - давайте разделим массив <tex>a[0...n-1]</tex> на 2 массива <tex>a[0...\frac{n}{2} - 1]</tex> и <tex>a[\frac{n}{2}...n-1]</tex> и рекурсивно решим задачу для каждого из них. Осталось научиться находить количество искомых пар <tex>(i, j)</tex>, таких что <tex>i < \frac{n}{2}, j >= \frac{n}{2}</tex>. Для этого воспользуемся другой известной техникой - методом двух указателей. Посчитаем массив префиксных сумм для правой половины <tex>pref[i] = \sum_{j=n/2}^{i} [a[j]]</tex> и суффиксных (<tex>suf[i] = \sum_{j=i}^{n/2 + 1} [a[i]]</tex>) - для левой. Заведем два указателя (<tex>p1</tex> и <tex>p2</tex>). Изначально установим <tex>p1 = \frac{n}{2} - l + 1, p2 = \frac{n}{2}</tex>. Пока <tex>p2 - 1> \frac{n}{2}</tex> и <tex>pref[p2] + suf[p1] > W </tex> будем уменьшать <math>p2</math> на <math>1</math>. Если после этого <math>pref[p2] + suf[p1] <= W</math>, то к ответу прибавим <math>(p2 - \frac{n}{2} + 1) * (\frac{n}{2} - p1)</math>, посго, увеличим <math>p1</math> на <math/math>. Так будем делать, пока <math>p1 < \frac{n}{2}</math>. В конце сложим текущий ответ и ответы для половин массива - получим ответ на задачу. | Первая задача решается методом [[Сортировка_слиянием|qevide&conqure (рус. разделяй и властвуй)]] - давайте разделим массив <tex>a[0...n-1]</tex> на 2 массива <tex>a[0...\frac{n}{2} - 1]</tex> и <tex>a[\frac{n}{2}...n-1]</tex> и рекурсивно решим задачу для каждого из них. Осталось научиться находить количество искомых пар <tex>(i, j)</tex>, таких что <tex>i < \frac{n}{2}, j >= \frac{n}{2}</tex>. Для этого воспользуемся другой известной техникой - методом двух указателей. Посчитаем массив префиксных сумм для правой половины <tex>pref[i] = \sum_{j=n/2}^{i} [a[j]]</tex> и суффиксных (<tex>suf[i] = \sum_{j=i}^{n/2 + 1} [a[i]]</tex>) - для левой. Заведем два указателя (<tex>p1</tex> и <tex>p2</tex>). Изначально установим <tex>p1 = \frac{n}{2} - l + 1, p2 = \frac{n}{2}</tex>. Пока <tex>p2 - 1> \frac{n}{2}</tex> и <tex>pref[p2] + suf[p1] > W </tex> будем уменьшать <math>p2</math> на <math>1</math>. Если после этого <math>pref[p2] + suf[p1] <= W</math>, то к ответу прибавим <math>(p2 - \frac{n}{2} + 1) * (\frac{n}{2} - p1)</math>, посго, увеличим <math>p1</math> на <math/math>. Так будем делать, пока <math>p1 < \frac{n}{2}</math>. В конце сложим текущий ответ и ответы для половин массива - получим ответ на задачу. | ||
− | Вторая задача имеет запросы на изменение и поэтому надо применить динамическую версию qevide&conqure - [[Дерево_отрезков._Построение|дерево отрезков]]. Построим дерево отрезков, | + | Вторая задача имеет запросы на изменение и поэтому надо применить динамическую версию qevide&conqure - [[Дерево_отрезков._Построение|дерево отрезков]]. Построим дерево отрезков, |
− | |||
− | |||
== Статическая центроидная декомпозиция == | == Статическая центроидная декомпозиция == |
Версия 00:13, 14 июня 2017
Centroid decomposition (рус. центроидная декомпозиция) - это структура данных, позволяющая отвечать на запросы на дереве. Чаще всего это запросы, связанные с нахождением функции на вершинах, связанных неравенством на расстояние между ними в дереве. Также иногда применяется для запросов на путях в дереве.
Содержание
Введение
Рассмотрим 2 задачи на обычном массиве (в дальнейшем мы будем их обобщать на случай дерева): Задача 1:
Задача: |
Есть массив | положительных целых чисел из элементов и числа и . Требуется найти количество пар индексов массива, таких что и .
Задача 2:
Задача: |
Есть прямая дорога, на которой расположены 1) дан город 3) дан город , в котором находится больной и требуется найти такой город , что минимально возможное. 2) дан город и сказано, что больше он не будет принимать больных и сказано, что теперь он может принимать больных | городов. В некоторых городах есть госпитали, которые могут принимать больных. Поступают запросы вида :
Для начала решим обе задачи. Первая задача решается методом qevide&conqure (рус. разделяй и властвуй) - давайте разделим массив на 2 массива и и рекурсивно решим задачу для каждого из них. Осталось научиться находить количество искомых пар , таких что . Для этого воспользуемся другой известной техникой - методом двух указателей. Посчитаем массив префиксных сумм для правой половины и суффиксных ( ) - для левой. Заведем два указателя ( и ). Изначально установим . Пока и будем уменьшать на . Если после этого , то к ответу прибавим , посго, увеличим на <math/math>. Так будем делать, пока . В конце сложим текущий ответ и ответы для половин массива - получим ответ на задачу.
Вторая задача имеет запросы на изменение и поэтому надо применить динамическую версию qevide&conqure - дерево отрезков. Построим дерево отрезков,