Heavy-light-декомпозиция: различия между версиями
Перейти к навигации
Перейти к поиску
Ctrlalt (обсуждение | вклад) Нет описания правки |
Ctrlalt (обсуждение | вклад) (→Ссылки) |
||
| Строка 125: | Строка 125: | ||
== Ссылки == | == Ссылки == | ||
* [ | Теория: | ||
* [ | * [https://e-maxx.ru/algo/heavy_light e-maxx.ru — Heavy-light декомпозиция] | ||
* [ | * [https://cp-algorithms.com/graph/hld.html cp-algorithms.com — Heavy-light decomposition] | ||
* [ | * [https://algorithmica.org/ru/hld algorithmica.org — Heavy-light декомпозиция] | ||
* [ | * [https://codeforces.com/blog/entry/12239 codeforces.com — Heavy-light decompositon — это может быть просто!] | ||
* [https://codeforces.com/blog/entry/81317 codeforces.com — Hybrid Tutorial #-1: Heavy-Light Decomposition] | |||
* [https://web.archive.org/web/20221128105153/https://blog.anudeep2011.com/heavy-light-decomposition/ blog.anudeep2011.com — Heavy Light Decomposition] | |||
* [https://usaco.guide/plat/hld usaco.guide — Heavy-Light Decomposition] | |||
Код: | |||
* [https://github.com/indy256/codelibrary/blob/main/cpp/structures/heavy_light_decomposition.cpp codelibrary/cpp/structures/heavy_light_decomposition.cpp] | |||
* [https://github.com/ADJA/algos/blob/master/Graphs/HLD.cpp algos/Graphs/HLD.cpp] | |||
* [https://github.com/ADJA/algos/blob/master/Graphs/LCAHLD.cpp algos/Graphs/LCAHLD.cpp] | |||
[[Категория:Учебный курс «Алгоритмы и структуры данных»]] | [[Категория:Учебный курс «Алгоритмы и структуры данных»]] | ||
Версия от 22:29, 14 февраля 2026
struct SegmentTree {
int size;
vector<int> t;
int query(int v, int vl, int vr, int l, int r) {
if (vr < l || r < vl)
return -1e9;
if (l <= vl && vr <= r)
return t[v];
int vm = vl + (vr - vl) / 2;
int ql = query(2 * v + 1, vl, vm, l, r);
int qr = query(2 * v + 2, vm + 1, vr, l, r);
return max(ql, qr);
}
void modify(int v, int vl, int vr, int index, int value) {
if (vr < index || index < vl)
return;
if (vl == vr) {
t[v] += value;
return;
}
int vm = vl + (vr - vl) / 2;
modify(2 * v + 1, vl, vm, index, value);
modify(2 * v + 2, vm + 1, vr, index, value);
t[v] = max(t[2 * v + 1], t[2 * v + 2]);
}
SegmentTree(int size) : size(size), t(4 * size) {}
int getMax(int l, int r) {
return query(0, 0, size - 1, l, r);
}
void addValue(int index, int value) {
modify(0, 0, size - 1, index, value);
}
};
struct HeavyLightDecomposition {
vector<vector<int>> graph;
vector<int> l, r, parent, subtreeSize;
int timer = 0;
vector<vector<int>> paths;
vector<int> pathOf, posOf;
vector<SegmentTree> segmentTrees;
HeavyLightDecomposition(int vertexCount) :
graph(vertexCount), l(vertexCount), r(vertexCount),
parent(vertexCount), subtreeSize(vertexCount),
pathOf(vertexCount), posOf(vertexCount) {}
void addEdge(int a, int b) {
graph[a].push_back(b);
graph[b].push_back(a);
}
int dfs(int v, int p) {
l[v] = timer++;
parent[v] = p;
subtreeSize[v] = 1;
for (int to : graph[v])
if (to != p)
subtreeSize[v] += dfs(to, v);
r[v] = timer++;
return subtreeSize[v];
}
bool isAncestor(int a, int b) {
return l[a] <= l[b] && r[b] <= r[a];
}
void buildPath(int v, int pathIndex) {
if (paths.size() == pathIndex)
paths.emplace_back();
paths[pathIndex].push_back(v);
pathOf[v] = pathIndex;
posOf[v] = paths[pathIndex].size() - 1;
int maxTo = -1;
for (int to : graph[v])
if (to != parent[v] && (maxTo == -1 || subtreeSize[maxTo] < subtreeSize[to]))
maxTo = to;
for (int to : graph[v]) {
if (to == parent[v])
continue;
if (to == maxTo)
buildPath(to, pathIndex);
else
buildPath(to, paths.size());
}
}
void prepare(int root) {
dfs(root, -1);
buildPath(root, 0);
for (vector<int> &path : paths)
segmentTrees.push_back(SegmentTree(path.size()));
}
int getMax(int a, int b) {
int res = 0;
for (; !isAncestor(paths[pathOf[a]][0], b); a = parent[paths[pathOf[a]][0]])
res = max(res, segmentTrees[pathOf[a]].getMax(0, posOf[a]));
for (; !isAncestor(paths[pathOf[b]][0], a); b = parent[paths[pathOf[b]][0]])
res = max(res, segmentTrees[pathOf[b]].getMax(0, posOf[b]));
if (posOf[a] > posOf[b])
swap(a, b);
return max(res, segmentTrees[pathOf[a]].getMax(posOf[a], posOf[b]));
}
void addValue(int v, int value) {
segmentTrees[pathOf[v]].addValue(posOf[v], value);
}
};
Ссылки на задачи
Ссылки
Теория:
- e-maxx.ru — Heavy-light декомпозиция
- cp-algorithms.com — Heavy-light decomposition
- algorithmica.org — Heavy-light декомпозиция
- codeforces.com — Heavy-light decompositon — это может быть просто!
- codeforces.com — Hybrid Tutorial #-1: Heavy-Light Decomposition
- blog.anudeep2011.com — Heavy Light Decomposition
- usaco.guide — Heavy-Light Decomposition
Код: