Tarjan 's off | Number of nodes in input tree ; COLOUR ' WHITE ' is assigned value 1 ; COLOUR ' BLACK ' is assigned value 2 ; A binary tree node has data , pointer to left child and a pointer to right child ; subset [ i ] . parent - . Holds the parent of node - ' i ' subset [ i ] . rank - . Holds the rank of node - ' i ' subset [ i ] . ancestor - . Holds the LCA queries answers subset [ i ] . child - . Holds one of the child of node - ' i ' if present , else - '0' subset [ i ] . sibling - . Holds the right - sibling of node - ' i ' if present , else - '0' subset [ i ] . color - . Holds the colour of node - ' i ' ; Structure to represent a query A query consists of ( L , R ) and we will process the queries offline a / c to Tarjan 's oflline LCA algorithm ; Helper function that allocates a new node with the given data and None left and right pointers . ; A utility function to make set ; A utility function to find set of an element i ( uses path compression technique ) ; Find root and make root as parent of i ( path compression ) ; A function that does union of two sets of x and y ( uses union by rank ) ; Attach smaller rank tree under root of high rank tree ( Union by Rank ) ; If ranks are same , then make one as root and increment its rank by one ; The main function that prints LCAs . u is root 's data. m is size of q[] ; Make Sets ; Initially , each node 's ancestor is the node  itself. ; This while loop doesn 't run for more than 2 times  as there can be at max. two children of a node ; This is basically an inorder traversal and we preprocess the arrays . child [ ] and sibling [ ] in " struct ▁ subset " with the tree structure using this function . ; Recur on left child ; Note that the below two lines can also be this - subsets [ node . data ] . child = node . right . data ; subsets [ node . right . data ] . sibling = node . left . data ; This is because if both left and right children of node - ' i ' are present then we can store any of them in subsets [ i ] . child and correspondingly its sibling ; Recur on right child ; A function to initialise prior to pre - processing and LCA walk ; Initialising the structure with 0 's  memset(subsets, 0, (V+1) * sizeof(struct subset)); ; Prints LCAs for given queries q [ 0. . m - 1 ] in a tree with given root ; Allocate memory for V subsets and nodes ; Creates subsets and colors them WHITE ; Preprocess the tree ; Perform a tree walk to process the LCA queries offline ; Driver code ; We construct a binary tree : - 1 / \ 2 3 / \ 4 5 ; LCA Queries to answer
V = 5 NEW_LINE WHITE = 1 NEW_LINE BLACK = 2 NEW_LINE class Node : NEW_LINE INDENT def __init__ ( self ) : NEW_LINE INDENT self . data = 0 NEW_LINE self . left = None NEW_LINE self . right = None NEW_LINE DEDENT DEDENT class subset : NEW_LINE INDENT def __init__ ( self ) : NEW_LINE INDENT self . parent = 0 NEW_LINE self . rank = 0 NEW_LINE self . ancestor = 0 NEW_LINE self . child = 0 NEW_LINE self . sibling = 0 NEW_LINE self . color = 0 NEW_LINE DEDENT DEDENT class Query : NEW_LINE INDENT def __init__ ( self , L , R ) : NEW_LINE INDENT self . L = L NEW_LINE self . R = R NEW_LINE DEDENT DEDENT def newNode ( data ) : NEW_LINE INDENT node = Node ( ) NEW_LINE node . data = data NEW_LINE node . left = node . right = None NEW_LINE return ( node ) NEW_LINE DEDENT def makeSet ( subsets , i ) : NEW_LINE INDENT if ( i < 1 or i > V ) : NEW_LINE INDENT return NEW_LINE DEDENT subsets [ i ] . color = WHITE NEW_LINE subsets [ i ] . parent = i NEW_LINE subsets [ i ] . rank = 0 NEW_LINE return NEW_LINE DEDENT def findSet ( subsets , i ) : NEW_LINE INDENT if ( subsets [ i ] . parent != i ) : NEW_LINE INDENT subsets [ i ] . parent = findSet ( subsets , subsets [ i ] . parent ) NEW_LINE DEDENT return subsets [ i ] . parent NEW_LINE DEDENT def unionSet ( subsets , x , y ) : NEW_LINE INDENT xroot = findSet ( subsets , x ) NEW_LINE yroot = findSet ( subsets , y ) NEW_LINE if ( subsets [ xroot ] . rank < subsets [ yroot ] . rank ) : NEW_LINE INDENT subsets [ xroot ] . parent = yroot NEW_LINE DEDENT elif ( subsets [ xroot ] . rank > subsets [ yroot ] . rank ) : NEW_LINE INDENT subsets [ yroot ] . parent = xroot NEW_LINE DEDENT else : NEW_LINE INDENT subsets [ yroot ] . parent = xroot NEW_LINE ( subsets [ xroot ] . rank ) += 1 NEW_LINE DEDENT DEDENT def lcaWalk ( u , q , m , subsets ) : NEW_LINE INDENT makeSet ( subsets , u ) NEW_LINE subsets [ findSet ( subsets , u ) ] . ancestor = u NEW_LINE child = subsets [ u ] . child NEW_LINE while ( child != 0 ) : NEW_LINE INDENT lcaWalk ( child , q , m , subsets ) NEW_LINE unionSet ( subsets , u , child ) NEW_LINE subsets [ findSet ( subsets , u ) ] . ancestor = u NEW_LINE child = subsets [ child ] . sibling NEW_LINE DEDENT subsets [ u ] . color = BLACK NEW_LINE for i in range ( m ) : NEW_LINE INDENT if ( q [ i ] . L == u ) : NEW_LINE INDENT if ( subsets [ q [ i ] . R ] . color == BLACK ) : NEW_LINE INDENT print ( " LCA ( % d ▁ % d ) ▁ - > ▁ % d " % ( q [ i ] . L , q [ i ] . R , subsets [ findSet ( subsets , q [ i ] . R ) ] . ancestor ) ) NEW_LINE DEDENT DEDENT elif ( q [ i ] . R == u ) : NEW_LINE INDENT if ( subsets [ q [ i ] . L ] . color == BLACK ) : NEW_LINE INDENT print ( " LCA ( % d ▁ % d ) ▁ - > ▁ % d " % ( q [ i ] . L , q [ i ] . R , subsets [ findSet ( subsets , q [ i ] . L ) ] . ancestor ) ) NEW_LINE DEDENT DEDENT DEDENT return NEW_LINE DEDENT def preprocess ( node , subsets ) : NEW_LINE INDENT if ( node == None ) : NEW_LINE INDENT return NEW_LINE DEDENT preprocess ( node . left , subsets ) NEW_LINE if ( node . left != None and node . right != None ) : NEW_LINE INDENT subsets [ node . data ] . child = node . left . data NEW_LINE subsets [ node . left . data ] . sibling = node . right . data NEW_LINE DEDENT elif ( ( node . left != None and node . right == None ) or ( node . left == None and node . right != None ) ) : NEW_LINE INDENT if ( node . left != None and node . right == None ) : NEW_LINE INDENT subsets [ node . data ] . child = node . left . data NEW_LINE DEDENT else : NEW_LINE INDENT subsets [ node . data ] . child = node . right . data NEW_LINE DEDENT DEDENT preprocess ( node . right , subsets ) NEW_LINE DEDENT def initialise ( subsets ) : NEW_LINE INDENT for i in range ( 1 , V + 1 ) : NEW_LINE INDENT subsets [ i ] . color = WHITE NEW_LINE DEDENT return NEW_LINE DEDENT def printLCAs ( root , q , m ) : NEW_LINE INDENT subsets = [ subset ( ) for _ in range ( V + 1 ) ] NEW_LINE initialise ( subsets ) NEW_LINE preprocess ( root , subsets ) NEW_LINE lcaWalk ( root . data , q , m , subsets ) NEW_LINE DEDENT if __name__ == " _ _ main _ _ " : NEW_LINE INDENT root = newNode ( 1 ) NEW_LINE root . left = newNode ( 2 ) NEW_LINE root . right = newNode ( 3 ) NEW_LINE root . left . left = newNode ( 4 ) NEW_LINE root . left . right = newNode ( 5 ) NEW_LINE q = [ Query ( 5 , 4 ) , Query ( 1 , 3 ) , Query ( 2 , 3 ) ] NEW_LINE m = len ( q ) NEW_LINE printLCAs ( root , q , m ) NEW_LINE DEDENT