1#include "../../../kyopro_library/template.hpp"
6 HLD(
int n) { resize(n); }
7 void add_edge(
int a,
int b) { g[a].push_back(b),g[b].push_back(a); }
8 void build(
int root=0) { dfs1(root),dfs2(root,root); }
9 HLD(
const vector<vector<
int>>& g,
int root=0) {
17
18
19
20
21
22
24 vector<tuple<
bool,
int,
int>> ret;
25 while(head[u]!=head[v]) {
26 if(dep[head[u]]>dep[head[v]]) {
27 ret.push_back({
true,pos[head[u]],pos[u]});
30 ret.push_back({
false,pos[head[v]],pos[v]});
34 if(dep[u]>dep[v]) ret.push_back({
true,pos[v],pos[u]});
35 else ret.push_back({
false,pos[u],pos[v]});
40 int lca(
int u,
int v) {
41 while(head[u]!=head[v]) {
42 if(dep[head[u]]>dep[head[v]]) u=par[head[u]];
45 return dep[u]<dep[v] ? u:v;
49 int at(
int v) {
return pos[v]; }
55 vector<vector<
int>> g;
56 vector<
int> sz,par,dep,head;
59 void resize(
int n) { g.resize(n),sz.resize(n),par.resize(n),dep.resize(n),pos.resize(n),head.resize(n),pos2.resize(n); }
60 void dfs1(
int now,
int pre=-1) {
71 void dfs2(
int now,
int a,
int pre=-1) {
80 for(
int nxt: g[now]) {
81 if(nxt==pre)
continue;
88 for(
int nxt: g[now]) {
89 if(nxt==pre || nxt==idx)
continue;
HL分解 解説:https://hcpc-hokudai.github.io/archive/graph_tree_001.pdf
void add_edge(int a, int b)
pair< int, int > subtree(int v)
HL分解後の列で、頂点vの部分木に対応する区間を返す
int at(int v)
頂点vのHL分解後の列での位置を返す
HLD(const vector< vector< int > > &g, int root=0)
int lca(int u, int v)
頂点 u, v のLCAを返す
vector< tuple< bool, int, int > > path(int u, int v)
頂点 u, v を結ぶパスをHL分解後の辺の列にして返す