C++ program:
#include <bits/stdc++.h>
#define MAX  100001
using namespace std ; struct Node { int data ; struct Node * left ; struct Node * right ; } ; struct Node * newNode ( int data ) { struct Node * temp = new struct Node ; temp -> data = data ; temp -> left = temp -> right = NULL ; return temp ; } int level [ MAX ] ; void FindLevels ( struct Node * root ) { if ( ! root ) return ; queue < pair < struct Node * , int > > q ; q . push ( { root , 0 } ) ; pair < struct Node * , int > p ; while ( ! q . empty ( ) ) { p = q . front ( ) ; q . pop ( ) ; level [ p . first -> data ] = p . second ; if ( p . first -> left ) q . push ( { p . first -> left , p . second + 1 } ) ; if ( p . first -> right ) q . push ( { p . first -> right , p . second + 1 } ) ; } } int Euler [ MAX ] ; int idx = 0 ; void eulerTree ( struct Node * root ) { Euler [ ++ idx ] = root -> data ; if ( root -> left ) { eulerTree ( root -> left ) ; Euler [ ++ idx ] = root -> data ; } if ( root -> right ) { eulerTree ( root -> right ) ; Euler [ ++ idx ] = root -> data ; } } int vis [ MAX ] ; int L [ MAX ] ; int H [ MAX ] ; void preprocessEuler ( int size ) { for ( int i = 1 ; i <= size ; i ++ ) { L [ i ] = level [ Euler [ i ] ] ; if ( vis [ Euler [ i ] ] == 0 ) { H [ Euler [ i ] ] = i ; vis [ Euler [ i ] ] = 1 ; } } } pair < int , int > seg [ 4 * MAX ] ; pair < int , int > min ( pair < int , int > a , pair < int , int > b ) { if ( a . first <= b . first ) return a ; else return b ; } pair < int , int > buildSegTree ( int low , int high , int pos ) { if ( low == high ) { seg [ pos ] . first = L [ low ] ; seg [ pos ] . second = low ; return seg [ pos ] ; } int mid = low + ( high - low ) / 2 ; buildSegTree ( low , mid , 2 * pos ) ; buildSegTree ( mid + 1 , high , 2 * pos + 1 ) ; seg [ pos ] = min ( seg [ 2 * pos ] , seg [ 2 * pos + 1 ] ) ; } pair < int , int > LCA ( int qlow , int qhigh , int low , int high , int pos ) { if ( qlow <= low && qhigh >= high ) return seg [ pos ] ; if ( qlow > high qhigh < low ) return { INT_MAX , 0 } ; int mid = low + ( high - low ) / 2 ; return min ( LCA ( qlow , qhigh , low , mid , 2 * pos ) , LCA ( qlow , qhigh , mid + 1 , high , 2 * pos + 1 ) ) ; } int findDistance ( int n1 , int n2 , int size ) { int prevn1 = n1 , prevn2 = n2 ; n1 = H [ n1 ] ; n2 = H [ n2 ] ; if ( n2 < n1 ) swap ( n1 , n2 ) ; int lca = LCA ( n1 , n2 , 1 , size , 1 ) . second ; lca = Euler [ lca ] ; return level [ prevn1 ] + level [ prevn2 ] - 2 * level [ lca ] ; } void preProcessing ( Node * root , int N ) { eulerTree ( root ) ; FindLevels ( root ) ; preprocessEuler ( 2 * N - 1 ) ; buildSegTree ( 1 , 2 * N - 1 , 1 ) ; } int main ( ) { int N = 8 ; 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 -> right -> left -> right = newNode ( 8 ) ; preProcessing ( root , N ) ; cout << " Dist ( 4 , ▁ 5 ) ▁ = ▁ " << findDistance ( 4 , 5 , 2 * N - 1 ) << " STRNEWLINE " ; cout << " Dist ( 4 , ▁ 6 ) ▁ = ▁ " << findDistance ( 4 , 6 , 2 * N - 1 ) << " STRNEWLINE " ; cout << " Dist ( 3 , ▁ 4 ) ▁ = ▁ " << findDistance ( 3 , 4 , 2 * N - 1 ) << " STRNEWLINE " ; cout << " Dist ( 2 , ▁ 4 ) ▁ = ▁ " << findDistance ( 2 , 4 , 2 * N - 1 ) << " STRNEWLINE " ; cout << " Dist ( 8 , ▁ 5 ) ▁ = ▁ " << findDistance ( 8 , 5 , 2 * N - 1 ) << " STRNEWLINE " ; return 0 ; }

Index/key variables: MAX, i, lca, low, n1, n2, pos, prevn1, prevn2
Accumulator variables: i, stdc
Iterator variables: i
Class/struct names: Node