RainX_69

CODECHEF-TALCA , BINARY LIFTING LCA

Dec 19th, 2022
109
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.84 KB | Source Code | 0 0
  1. /*
  2. In a rooted tree, the (or LCA for short) of two vertices u and v is defined as the lowest vertex that is ancestor of both that two vertices.
  3.  
  4.  
  5. Given a tree of N vertices, you need to answer the question of the form "r u v" which means if the root of the tree is at r then what is LCA of u and v.
  6.  
  7. Input
  8.  
  9. The first line contains a single integer N. Each line in the next N - 1 lines contains a pair of integer u and v representing a edge between this two vertices.
  10. The next line contains a single integer Q which is the number of the queries. Each line in the next Q lines contains three integers r, u, v representing a query.
  11.  
  12. Output
  13. For each query, write out the answer on a single line.
  14.  
  15. Constraints
  16.  
  17. 1 ≤ N, Q ≤ 2 × 10^5
  18.  
  19.  
  20. Example
  21. Input:
  22. 4
  23. 1 2
  24. 2 3
  25. 1 4
  26. 2
  27. 1 4 2
  28. 2 4 2
  29.  
  30. Output:
  31. 1
  32. 2
  33.  
  34. Explanation
  35. "1 4 2": if 1 is the root, it is parent of both 2 and 4 so LCA of 2 and 4 is 1.
  36. "2 4 2": the root of the tree is at 2, according to the definition, LCA of any vertex with 2 is 2.
  37. */
  38.  
  39. #include<bits/stdc++.h>
  40. using namespace std;
  41.  
  42. vector<vector<int>> dp(200001,vector<int>(20,-1));
  43. vector<int> level(200001,0);
  44. vector<int> parent(200001,0);
  45. vector<int> adj[200001];
  46.  
  47.  
  48. void DFS(int node, int depth, int par){
  49.     level[node]=depth;
  50.     parent[node]=par;
  51.     for(auto nei: adj[node]){
  52.         if(nei!=par){
  53.             DFS(nei,depth+1,node);
  54.         }
  55.     }
  56. }
  57.  
  58. void precomputation(int n){
  59.     for(int node=1;node<=n;node++){
  60.         dp[node][0]=parent[node];
  61.     }
  62.     for(int node=1;node<=n;node++){
  63.         for(int jump=1;jump<20;jump++){
  64.             if(dp[node][jump-1]!=-1){
  65.                 dp[node][jump]=dp[dp[node][jump-1]][jump-1];
  66.             }
  67.         }
  68.     }
  69. }
  70.  
  71. void moveUP(int &u, int v){
  72.     int k=level[u]-level[v];
  73.     for(int i=19;i>=0;i--){
  74.         if(k>=pow(2,i)){
  75.             k-=pow(2,i);
  76.             u=dp[u][i];
  77.         }
  78.     }
  79. }
  80.  
  81. int LCA(int node1, int node2){
  82.     if(level[node1]>level[node2]){
  83.         moveUP(node1,node2);
  84.     }
  85.     if(level[node1]<level[node2]){
  86.         moveUP(node2,node1);
  87.     }
  88.     if(node1==node2){
  89.         return node1;
  90.     }
  91.     for(int jump=19;jump>=0;jump--){
  92.         if(dp[node1][jump]!=dp[node2][jump]){
  93.             node1=dp[node1][jump];
  94.             node2=dp[node2][jump];
  95.         }
  96.     }
  97.     return dp[node1][0];
  98. }
  99.  
  100.  
  101. void solve(){
  102.     int N;
  103.     cin>>N;
  104.     for(int i=0;i<N-1;i++){
  105.         int node1,node2;
  106.         cin>>node1>>node2;
  107.         adj[node1].push_back(node2);
  108.         adj[node2].push_back(node1);
  109.     }
  110.     DFS(1,0,0);
  111.     precomputation(N);
  112.     int q;
  113.     cin>>q;
  114.     while(q--){
  115.         int r,u,v;
  116.         cin>>r>>u>>v;
  117.        
  118.         int a=LCA(u,v);
  119.                 int b=LCA(r,u);
  120.                 int c=LCA(r,v);
  121.        
  122.                 if(a==b) cout<<c<<endl;
  123.                 else if(b==c) cout<<a<<endl;
  124.             else if(a==c) cout<<b<<endl;
  125.     }
  126. }
  127.  
  128. int main(){
  129.     solve();
  130.     return 0;
  131. }
Advertisement
Add Comment
Please, Sign In to add comment