Lowest Common Ancestor in a Binary Tree | Set 3 ( Using RMQ ) | C # code to find LCA of given two nodes in a tree ; the graph ; level of each node ; the segment tree ; adding edges to the graph ( tree ) ; assigning level to nodes ; storing the dfs traversal in the array e ; making the array l ; making the array h ; if is already stored ; Range minimum query to return the index of minimum in the subarray L [ qs : qe ] ; out of range ; in the range ; constructs the segment tree ; leaf ; Function to get LCA ; Driver code ; n = number of nodes in the tree q = number of queries to answer ; 1 / | \ 2 3 4 | \ 5 6 / | \ 8 7 9 ( right of 5 ) / | \ | \ 10 11 12 13 14 | 15
using System ; using System . Collections . Generic ; public class GFG { static int maxn = 100005 ; static int left ( int i ) { return ( 2 * i + 1 ) ; } static int right ( int i ) { return 2 * i + 2 ; } static List < int > [ ] g = new List < int > [ maxn ] ; static int [ ] level = new int [ maxn ] ; static List < int > e = new List < int > ( ) ; static List < int > l = new List < int > ( ) ; static int [ ] h = new int [ maxn ] ; static int [ ] st ; static void add_edge ( int u , int v ) { g [ u ] . Add ( v ) ; g [ v ] . Add ( u ) ; } static void leveling ( int src ) { for ( int i = 0 ; i < ( g [ src ] . Count ) ; i ++ ) { int des = g [ src ] [ i ] ; if ( level [ des ] != 0 ) { level [ des ] = level [ src ] + 1 ; leveling ( des ) ; } } } static bool [ ] visited = new bool [ maxn ] ; static void dfs ( int src ) { e . Add ( src ) ; visited [ src ] = true ; for ( int i = 0 ; i < ( g [ src ] ) . Count ; i ++ ) { int des = g [ src ] [ i ] ; if ( ! visited [ des ] ) { dfs ( des ) ; e . Add ( src ) ; } } } static void setting_l ( int n ) { for ( int i = 0 ; i < e . Count ; i ++ ) l . Add ( level [ e [ i ] ] ) ; } static void setting_h ( int n ) { for ( int i = 0 ; i <= n ; i ++ ) h [ i ] = - 1 ; for ( int i = 0 ; i < e . Count ; i ++ ) { if ( h [ e [ i ] ] == - 1 ) h [ e [ i ] ] = i ; } } static int RMQ ( int ss , int se , int qs , int qe , int i ) { if ( ss > se ) return - 1 ; if ( se < qs < ss ) return - 1 ; if ( qs <= ss && se <= qe ) return st [ i ] ; int mid = ( ss + se ) / 2 ; int sti = RMQ ( ss , mid , qs , qe , left ( i ) ) ; int en = RMQ ( mid + 1 , se , qs , qe , right ( i ) ) ; if ( sti != - 1 && en != - 1 ) { if ( l [ sti ] < l [ en ] ) return sti ; return en ; } else if ( sti != - 1 ) return sti - 2 ; else if ( en != - 1 ) return en - 1 ; return 0 ; } static void SegmentTreeConstruction ( int ss , int se , int i ) { if ( ss > se ) return ; if ( ss == se ) { st [ i ] = ss ; return ; } int mid = ( ss + se ) / 2 ; SegmentTreeConstruction ( ss , mid , left ( i ) ) ; SegmentTreeConstruction ( mid + 1 , se , right ( i ) ) ; if ( l [ st [ left ( i ) ] ] < l [ st [ right ( i ) ] ] ) st [ i ] = st [ left ( i ) ] ; else st [ i ] = st [ right ( i ) ] ; } static int LCA ( int x , int y ) { if ( h [ x ] > h [ y ] ) { int t = x ; x = y ; y = t ; } return e [ RMQ ( 0 , l . Count - 1 , h [ x ] , h [ y ] , 0 ) ] ; } public static void Main ( String [ ] args ) { st = new int [ 5 * maxn ] ; int n = 15 ; for ( int i = 0 ; i < g . Length ; i ++ ) g [ i ] = new List < int > ( ) ; add_edge ( 1 , 2 ) ; add_edge ( 1 , 3 ) ; add_edge ( 1 , 4 ) ; add_edge ( 3 , 5 ) ; add_edge ( 4 , 6 ) ; add_edge ( 5 , 7 ) ; add_edge ( 5 , 8 ) ; add_edge ( 5 , 9 ) ; add_edge ( 7 , 10 ) ; add_edge ( 7 , 11 ) ; add_edge ( 7 , 12 ) ; add_edge ( 9 , 13 ) ; add_edge ( 9 , 14 ) ; add_edge ( 12 , 15 ) ; level [ 1 ] = 1 ; leveling ( 1 ) ; dfs ( 1 ) ; setting_l ( n ) ; setting_h ( n ) ; SegmentTreeConstruction ( 0 , l . Count - 1 , 0 ) ; Console . Write ( LCA ( 10 , 15 ) + " STRNEWLINE " ) ; Console . Write ( LCA ( 11 , 14 ) + " STRNEWLINE " ) ; } }