give_us_tmp/lca.cpp
Code
/**
* LCA
*
* 構築 :O(N)
* LCA :O(1)
* 距離 :O(1)
*
* verified with :https://judge.yosupo.jp/problem/lca
* submission :https://judge.yosupo.jp/submission/28297
*/
struct lca{
using graph=vector<vector<int>>;
graph g;
vector<int>sz,in,out,nxt,par;
lca(const graph& g,int s):g(g){
int n=g.size();
sz.resize(n,0);
in.resize(n,0);
out.resize(n,0);
nxt.resize(n,s);
par.resize(n,s);
dfs_sz(s,-1);
dfs_hld(s,-1);
}
void dfs_sz(int v,int p) {
sz[v] = 1;
for(auto &u: g[v]) {
if(p==u)continue;
dfs_sz(u,v);
sz[v]+=sz[u];
if(sz[u]>sz[g[v][0]])std::swap(u,g[v][0]);
}
}
void dfs_hld(int v,int p) {
static int t=0;
in[v]=t++;
for(auto u: g[v]){
if(p==u)continue;
nxt[u]=(u==g[v][0]?nxt[v]:u);
par[u]=(u==g[v][0]?par[v]:v);
dfs_hld(u,v);
}
out[v] = t;
}
int query(int s,int t){
while(nxt[s]!=nxt[t]){
if(sz[nxt[s]]>sz[nxt[t]])t=par[t];
else s=par[s];
}
return sz[s]>sz[t]?s:t;
}
int distance(int s,int t){
int res=0;
while(nxt[s]!=nxt[t]){
if(sz[nxt[s]]>sz[nxt[t]]){
res+=in[t]-in[nxt[t]]+1;
t=par[t];
}
else {
res+=in[s]-in[nxt[s]]+1;
s=par[s];
}
}
return res+std::abs(in[s]-in[t]);
}
};
#line 1 "give_us_tmp/lca.cpp"
/**
* LCA
*
* 構築 :O(N)
* LCA :O(1)
* 距離 :O(1)
*
* verified with :https://judge.yosupo.jp/problem/lca
* submission :https://judge.yosupo.jp/submission/28297
*/
struct lca{
using graph=vector<vector<int>>;
graph g;
vector<int>sz,in,out,nxt,par;
lca(const graph& g,int s):g(g){
int n=g.size();
sz.resize(n,0);
in.resize(n,0);
out.resize(n,0);
nxt.resize(n,s);
par.resize(n,s);
dfs_sz(s,-1);
dfs_hld(s,-1);
}
void dfs_sz(int v,int p) {
sz[v] = 1;
for(auto &u: g[v]) {
if(p==u)continue;
dfs_sz(u,v);
sz[v]+=sz[u];
if(sz[u]>sz[g[v][0]])std::swap(u,g[v][0]);
}
}
void dfs_hld(int v,int p) {
static int t=0;
in[v]=t++;
for(auto u: g[v]){
if(p==u)continue;
nxt[u]=(u==g[v][0]?nxt[v]:u);
par[u]=(u==g[v][0]?par[v]:v);
dfs_hld(u,v);
}
out[v] = t;
}
int query(int s,int t){
while(nxt[s]!=nxt[t]){
if(sz[nxt[s]]>sz[nxt[t]])t=par[t];
else s=par[s];
}
return sz[s]>sz[t]?s:t;
}
int distance(int s,int t){
int res=0;
while(nxt[s]!=nxt[t]){
if(sz[nxt[s]]>sz[nxt[t]]){
res+=in[t]-in[nxt[t]]+1;
t=par[t];
}
else {
res+=in[s]-in[nxt[s]]+1;
s=par[s];
}
}
return res+std::abs(in[s]-in[t]);
}
};
Back to top page