|
| 1 | +--- |
| 2 | +title: Static top tree |
| 3 | +documentation_of: ./static_toptree.hpp |
| 4 | +--- |
| 5 | + |
| 6 | +いわゆる Static top tree を扱う.根付き木の部分木に関する各種演算をクエリあたり $O(n \log n)$ で行える. |
| 7 | + |
| 8 | +## 原理 |
| 9 | + |
| 10 | +Static top tree のしくみについては [解説 - AtCoder Beginner Contest 351](https://atcoder.jp/contests/abc351/editorial/9868) 等も併せて参照されたい. |
| 11 | + |
| 12 | +Static top tree は,根付き木をもとに平衡二分木を構築する.平衡二分木の各頂点には `PointCluster` と `PathCluster` の 2 種類のデータ構造のいずれかが載る. |
| 13 | + |
| 14 | +例えば,入力として以下の根付き木( $0$ が根)を与えた場合に構築される static top tree を下に示す.ここで入力の木の辺のうち二重線は heavy-light decomposition (HLD) の heavy edge, 破線は light edge を示す. |
| 15 | + |
| 16 | + |
| 17 | + |
| 18 | + |
| 19 | + |
| 20 | +出力の辺のうち実線は PathCluster, 破線は PointCluster が親頂点に伝播されることをそれぞれ意味する. |
| 21 | + |
| 22 | +図から分かるように,HLD の heavy path は PathCluster として管理され, compress 処理によってマージされる.また, light edge で親と繋がる子頂点たちは PointCluster として管理され, rake 処理によってマージされる.これらの処理を問題に応じてうまく考案・実装してやる必要がある. |
| 23 | + |
| 24 | +## 使用方法 |
| 25 | + |
| 26 | +まず,以下のように `Point` クラス・ `Path` クラスと `vertex()` / `compress()` / `rake()` / `add_edge()` / `add_vertex()` メソッドを持つクラスを定義する( `static` はなくても可). |
| 27 | + |
| 28 | +```cpp |
| 29 | +struct tree_dp { |
| 30 | + // Point Cluster |
| 31 | + struct Point {}; |
| 32 | + |
| 33 | + // Path Cluster |
| 34 | + struct Path {}; |
| 35 | + |
| 36 | + Path vertex(int i); |
| 37 | + |
| 38 | + static Path compress(const Path &parent, const Path &child); |
| 39 | + |
| 40 | + static Point rake(const Point &l, const Point &r); |
| 41 | + |
| 42 | + static Point add_edge(const Path &d); |
| 43 | + |
| 44 | + Path add_vertex(const Point &d, int i); |
| 45 | +}; |
| 46 | +``` |
| 47 | +
|
| 48 | +その後,以下の手順で構築・利用する. |
| 49 | +
|
| 50 | +```cpp |
| 51 | +// 前準備 |
| 52 | +vector<vector<int>> to; // 隣接リスト |
| 53 | +int root = 0; |
| 54 | +
|
| 55 | +// 構築 |
| 56 | +const static_toptree_structure stts(to, root); |
| 57 | +tree_dp dp; |
| 58 | +static_toptree tree(stts, dp); |
| 59 | +
|
| 60 | +// 利用 |
| 61 | +tree.set(u); // 頂点 u に更新があった場合に呼ぶ |
| 62 | +
|
| 63 | +auto p = tree.all_prod(); // 根に関して値取得 |
| 64 | +``` |
| 65 | + |
| 66 | +## 問題例 |
| 67 | + |
| 68 | +- [AtCoder Beginner Contest 351 G - Hash on Tree](https://atcoder.jp/contests/abc351/tasks/abc351_g) |
| 69 | +- [Library Checker: Point Set Tree Path Composite Sum (Fixed Root)](https://judge.yosupo.jp/problem/point_set_tree_path_composite_sum_fixed_root) |
0 commit comments