You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Quick lowest-common-ancestor queries using sparse tables. The function lca(x,y) takes two node identifiers in a rooted tree and returns their lowest common ancestor (LCA for short). The function takes O(lg N) time where N is the number of nodes in the tree. A O(N lg N) pre-processing step is needed to build the sparse table.
API
void init( void ); // Initialize the module (assumes that the tree is built and the number of nodes is stored in variable n
void lca(int x, int y) // Lowest common ancestor of x and y
Other uses
This data structure can also be used to quickly answer path-queries in a (weighted) rooted tree. Examples include:
Find sum of weights on path from node x to node y.
Find min/max edge weight on path from node x to node y.
Find weight of path from node x to node y.
The data structure can support updates by adding a function to update the sparse table. An update can be implemented in time O(lg N) so both operations are fast.
Implementation
#include<cstdio>
#include<vector>
#include<iostream>
#include<algorithm>usingnamespacestd;constint N = 1000010; /* Max nodes */constint M = 30; /* Max LOG */int LG;
int n;
vector<int> adj[N]; /* Adjacency list */int p[N][M]; /* Sparse table */int depth[N];
voidinit( void ) {
LG = 0;
while((1 << LG) < n)
LG += 1;
for(int i = 0; i < n; i++)
for(int j = 0; j < LG; j++)
p[i][j] = -1;
}
voiddfs(int x, int par = -1, int d = 0) {
depth[x] = d;
p[x][0] = par;
for(int i = 1; i < LG; i++)
if(p[x][i - 1] + 1)
p[x][i] = p[p[x][i - 1]][i - 1];
for(auto y: adj[x])
if(y != par)
dfs(y, x, d + 1);
}
intlca(int x, int y) {
if(depth[x] > depth[y])
swap(x, y);
for(int i = LG - 1; i >= 0; i--)
if((p[y][i] + 1) && (depth[p[y][i]] >= depth[x]))
y = p[y][i];
if(x == y)
return x;
for(int i = LG - 1; i >= 0; i--)
if((p[x][i] + 1) && (p[x][i] != p[y][i]))
x = p[x][i], y = p[y][i];
return p[x][0];
}
/* Example */intmain( void ) {
cin >> n;
for(int i = 0; i < n; i++)
adj[i].clear();
for(int i = 0; i < n; i++) {
int len;
cin >> len;
while(len--) {
int x;
cin >> x;
adj[i].push_back(x);
adj[x].push_back(i);
}
}
/* Init and pre-process */init();
dfs(0);
/* Answer queries */int q;
cin >> q;
while(q--) {
int x, y;
cin >> x >> y;
cout << lca(x, y) << endl;
}
return0;
}
The text was updated successfully, but these errors were encountered:
LCA
Quick lowest-common-ancestor queries using sparse tables. The function
lca(x,y)
takes two node identifiers in a rooted tree and returns their lowest common ancestor (LCA for short). The function takesO(lg N)
time whereN
is the number of nodes in the tree. AO(N lg N)
pre-processing step is needed to build the sparse table.API
void init( void ); // Initialize the module (assumes that the tree is built and the number of nodes is stored in variable n
void lca(int x, int y) // Lowest common ancestor of x and y
Other uses
This data structure can also be used to quickly answer path-queries in a (weighted) rooted tree. Examples include:
The data structure can support updates by adding a function to update the sparse table. An update can be implemented in time
O(lg N)
so both operations are fast.Implementation
The text was updated successfully, but these errors were encountered: