Advertisement
arujbansal

Binary Lifting

Dec 23rd, 2020
764
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 1.84 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. const int MAXN = 1e5 + 5, MAXK = 20;
  6. vector<int> g[MAXN]; // Graph
  7. int timer; // Counter
  8. // Time of entering, Time of leaving, Binary lifting table
  9. int tin[MAXN], tout[MAXN], par[MAXN][MAXK];
  10.  
  11. void dfs(int u, int p) {
  12.     tin[u] = timer++;
  13.  
  14.     for (int j = 1; j < MAXK; j++) {
  15.         // 2^x = 2^(x - 1) + 2^(x - 1)
  16.         int lift = par[u][j - 1];
  17.         par[u][j] = par[lift][j - 1];    
  18.     }
  19.  
  20.     for (const auto &v : g[u]) {
  21.         if (v == p) continue;
  22.  
  23.         // 2^0 (direct) parent of the node we are about to visit is the current node
  24.         par[v][0] = u;
  25.         dfs(v, u);
  26.     }
  27.  
  28.     tout[u] = timer - 1;
  29. }
  30.  
  31. // Is u an ancestor of v?
  32. bool isAnc(int u, int v) {
  33.     // Time of entering u has to be less than time of entering v
  34.     // Time of leaving u has to be greater than time of leaving v
  35.     return tin[u] <= tin[v] && tout[u] >= tout[v];
  36. }
  37.  
  38. // Finds the LCA
  39. int query(int u, int v) {
  40.     // Check if u is an ancestor of v or if v is an ancestor of u
  41.     if (isAnc(u, v)) return u;
  42.     if (isAnc(v, u)) return v;
  43.  
  44.     for (int j = MAXK - 1; j >= 0; j--) {
  45.         int lift = par[u][j];
  46.        
  47.         if (!isAnc(lift, v)) {
  48.             u = lift;
  49.         }
  50.     }
  51.  
  52.     // The direct parent of u is the LCA
  53.     return par[u][0];
  54. }
  55.  
  56. int main() {
  57.     int N; // Number of vertices in the graph
  58.     cin >> N;
  59.  
  60.     // Input edges
  61.     for (int i = 0; i < N - 1; i++) {
  62.         int u, v;
  63.         cin >> u >> v;
  64.         u--, v--; // Convert to 0 based indexing
  65.  
  66.         g[u].push_back(v);
  67.         g[v].push_back(u);
  68.     }
  69.  
  70.     dfs(0, -1); // Tree is rooted at node 0
  71.  
  72.     int Q; // Number of queries
  73.     cin >> Q;
  74.  
  75.     while (Q--) {
  76.         int u, v;
  77.         cin >> u >> v;
  78.         u--, v--;
  79.  
  80.         cout << query(u, v) + 1 << "\n";
  81.     }
  82. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement