This documentation is automatically generated by online-judge-tools/verification-helper
#include "Graph/auxiliarytree.hpp"
#pragma once
#include "Graph/lca.hpp"
struct AuxiliaryTree{
int n,pos;
LCA lca;
vector<int> in,dep;
vector<vector<int>> _g,g;
AuxiliaryTree(int _n):n(_n),pos(0),lca(n),in(n),dep(n),_g(n),g(n){}
void add_edge(int u,int v){
lca.add_edge(u,v);
_g[u].push_back(v);
_g[v].push_back(u);
}
void run(int root=0){
lca.run(root);
dfs(root,-1);
}
void query(vector<int>& vs){
sort(ALL(vs),[&](int u,int v){return in[u]<in[v];});
vs.erase(unique(ALL(vs)),vs.end());
int m=vs.size();
stack<int> st;
st.push(vs[0]);
rep(i,0,m-1){
int w=lca.lca(vs[i],vs[i+1]);
if(w!=vs[i]){
int cur=st.top();
st.pop();
while(!st.empty() and dep[w]<dep[st.top()]){
add(st.top(),cur);
cur=st.top();
st.pop();
}
if(st.empty() or st.top()!=w){
st.push(w);
vs.push_back(w);
}
add(w,cur);
}
st.push(vs[i+1]);
}
while(st.size()>1){
int c=st.top();
st.pop();
add(st.top(),c);
}
}
void clear(vector<int>& vs){
for(auto& w:vs)g[w].clear();
}
private:
void dfs(int v,int p){
in[v]=pos++;
for(auto& to:_g[v])if(to!=p){
dep[to]=dep[v]+1;
dfs(to,v);
}
}
void add(int u,int v){
g[u].push_back(v);
g[v].push_back(u);
}
};
/**
* @brief Auxiliary Tree(Virtual Tree)
*/
#line 2 "Graph/auxiliarytree.hpp"
#line 2 "Graph/lca.hpp"
struct LCA {
LCA(int _n = 0) : n(_n), g(_n), depth(_n + 1, inf), start(_n) {}
void add_edge(int u, int v) {
g[u].push_back(v);
g[v].push_back(u);
}
void run(int root = 0) {
depth[root] = 0;
dfs(root, -1);
N = 1;
while (N < int(euler.size()))
N <<= 1;
tree.resize(N * 2, n);
rep(i, 0, euler.size()) tree[N + i] = euler[i];
for (int i = N - 1; i > 0; i--)
tree[i] = op(tree[i * 2], tree[i * 2 + 1]);
}
int lca(int u, int v) {
int a = start[u], b = start[v];
if (a > b)
swap(a, b);
b++;
int res = n;
for (int T = b - a; T >= 1; T = b - a) {
int x = a | ((1U << 31) >> __builtin_clz(T));
int y = x & -x, k = __builtin_ctz(x);
res = op(res, tree[(N | a) >> k]);
a += y;
}
return res;
}
int dist(int u, int v) {
return depth[u] + depth[v] - depth[lca(u, v)] * 2;
}
private:
int n, N;
vector<vector<int>> g;
vector<int> depth, start, euler, tree;
void dfs(int v, int p) {
start[v] = euler.size();
euler.push_back(v);
for (auto &to : g[v])
if (to != p) {
depth[to] = depth[v] + 1;
dfs(to, v);
euler.push_back(v);
}
}
int op(int u, int v) {
if (depth[u] < depth[v])
return u;
else
return v;
}
};
/**
* @brief Lowest Common Ancestor
*/
#line 4 "Graph/auxiliarytree.hpp"
struct AuxiliaryTree{
int n,pos;
LCA lca;
vector<int> in,dep;
vector<vector<int>> _g,g;
AuxiliaryTree(int _n):n(_n),pos(0),lca(n),in(n),dep(n),_g(n),g(n){}
void add_edge(int u,int v){
lca.add_edge(u,v);
_g[u].push_back(v);
_g[v].push_back(u);
}
void run(int root=0){
lca.run(root);
dfs(root,-1);
}
void query(vector<int>& vs){
sort(ALL(vs),[&](int u,int v){return in[u]<in[v];});
vs.erase(unique(ALL(vs)),vs.end());
int m=vs.size();
stack<int> st;
st.push(vs[0]);
rep(i,0,m-1){
int w=lca.lca(vs[i],vs[i+1]);
if(w!=vs[i]){
int cur=st.top();
st.pop();
while(!st.empty() and dep[w]<dep[st.top()]){
add(st.top(),cur);
cur=st.top();
st.pop();
}
if(st.empty() or st.top()!=w){
st.push(w);
vs.push_back(w);
}
add(w,cur);
}
st.push(vs[i+1]);
}
while(st.size()>1){
int c=st.top();
st.pop();
add(st.top(),c);
}
}
void clear(vector<int>& vs){
for(auto& w:vs)g[w].clear();
}
private:
void dfs(int v,int p){
in[v]=pos++;
for(auto& to:_g[v])if(to!=p){
dep[to]=dep[v]+1;
dfs(to,v);
}
}
void add(int u,int v){
g[u].push_back(v);
g[v].push_back(u);
}
};
/**
* @brief Auxiliary Tree(Virtual Tree)
*/