/* C++ Program to find LCA of u and v by reducing the problem to RMQ */ #include<bits/stdc++.h> #define V 9 // number of nodes in input tree int euler[2*V - 1]; // For Euler tour sequence int level[2*V - 1]; // Level of nodes in tour sequence int firstOccurrence[V+1]; // First occurrences of nodes in tour int ind; // Variable to fill-in euler and level arrays // A Binary Tree node struct Node { int key; struct Node *left, *right; }; // Utility function creates a new binary tree node with given key Node * newNode(int k) { Node *temp = new Node; temp->key = k; temp->left = temp->right = NULL; return temp; } // log base 2 of x int Log2(int x) { int ans = 0 ; while (x>>=1) ans++; return ans ; } /* A recursive function to get the minimum value in a given range of array indexes. The following are parameters for this function. st --> Pointer to segment tree index --> Index of current node in the segment tree. Initially 0 is passed as root is always at index 0 ss & se --> Starting and ending indexes of the segment represented by current node, i.e., st[index] qs & qe --> Starting and ending indexes of query range */ int RMQUtil(int index, int ss, int se, int qs, int qe, int *st) { // If segment of this node is a part of given range, then return // the min of the segment if (qs <= ss && qe >= se) return st[index]; // If segment of this node is outside the given range else if (se < qs || ss > qe) return -1; // If a part of this segment overlaps with the given range int mid = (ss + se)/2; int q1 = RMQUtil(2*index+1, ss, mid, qs, qe, st); int q2 = RMQUtil(2*index+2, mid+1, se, qs, qe, st); if (q1==-1) return q2; else if (q2==-1) return q1; return (level[q1] < level[q2]) ? q1 : q2; } // Return minimum of elements in range from index qs (query start) to // qe (query end). It mainly uses RMQUtil() int RMQ(int *st, int n, int qs, int qe) { // Check for erroneous input values if (qs < 0 || qe > n-1 || qs > qe) { printf("Invalid Input"); return -1; } return RMQUtil(0, 0, n-1, qs, qe, st); } // A recursive function that constructs Segment Tree for array[ss..se]. // si is index of current node in segment tree st void constructSTUtil(int si, int ss, int se, int arr[], int *st) { // If there is one element in array, store it in current node of // segment tree and return if (ss == se)st[si] = ss; else { // If there are more than one elements, then recur for left and // right subtrees and store the minimum of two values in this node int mid = (ss + se)/2; constructSTUtil(si*2+1, ss, mid, arr, st); constructSTUtil(si*2+2, mid+1, se, arr, st); if (arr[st[2*si+1]] < arr[st[2*si+2]]) st[si] = st[2*si+1]; else st[si] = st[2*si+2]; } } /* Function to construct segment tree from given array. This function allocates memory for segment tree and calls constructSTUtil() to fill the allocated memory */ int *constructST(int arr[], int n) { // Allocate memory for segment tree // Height of segment tree int x = Log2(n)+1; // Maximum size of segment tree int max_size = 2*(1<<x) - 1; // 2*pow(2,x) -1 int *st = new int[max_size]; // Fill the allocated memory st constructSTUtil(0, 0, n-1, arr, st); // Return the constructed segment tree return st; } // Recursive version of the Euler tour of T void eulerTour(Node *root, int l) { /* if the passed node exists */ if (root) { euler[ind] = root->key; // insert in euler array level[ind] = l; // insert l in level array ind++; // increment index /* if unvisited, mark first occurrence */ if (firstOccurrence[root->key] == -1) firstOccurrence[root->key] = ind-1; /* tour left subtree if exists, and remark euler and level arrays for parent on return */ if (root->left) { eulerTour(root->left, l+1); euler[ind]=root->key; level[ind] = l; ind++; } /* tour right subtree if exists, and remark euler and level arrays for parent on return */ if (root->right) { eulerTour(root->right, l+1); euler[ind]=root->key; level[ind] = l; ind++; } } } // Returns LCA of nodes n1, n2 (assuming they are // present in the tree) int findLCA(Node *root, int u, int v) { /* Mark all nodes unvisited. Note that the size of firstOccurrence is 1 as node values which vary from 1 to 9 are used as indexes */ memset(firstOccurrence, -1, sizeof(int)*(V+1)); /* To start filling euler and level arrays from index 0 */ ind = 0; /* Start Euler tour with root node on level 0 */ eulerTour(root, 0); /* construct segment tree on level array */ int *st = constructST(level, 2*V-1); /* If v before u in Euler tour. For RMQ to work, first parameter 'u' must be smaller than second 'v' */ if (firstOccurrence[u]>firstOccurrence[v]) std::swap(u, v); // Starting and ending indexes of query range int qs = firstOccurrence[u]; int qe = firstOccurrence[v]; // query for index of LCA in tour int index = RMQ(st, 2*V-1, qs, qe); /* return LCA node */ return euler[index]; } // Driver program to test above functions int main() { // Let us create the Binary Tree as shown in the diagram. Node * root = newNode(1); root->left = newNode(2); root->right = newNode(3); root->left->left = newNode(4); root->left->right = newNode(5); root->right->left = newNode(6); root->right->right = newNode(7); root->left->right->left = newNode(8); root->left->right->right = newNode(9); int u = 4, v = 9; printf("The LCA of node %d and node %d is node %d.\n", u, v, findLCA(root, u, v)); return 0; }