JAVA|segment tree|DFS|
Intuition\n Describe your first thoughts on how to solve this problem. \n\n# Approach\n Describe your approach to solving the problem. \n\n# Complexity\n- Time 
# Intuition\n<!-- Describe your first thoughts on how to solve this problem. -->\n\n# Approach\n<!-- Describe your approach to solving the problem. -->\n\n# Complexity\n- Time complexity:\n<!-- Add your time complexity here, e.g. $$O(n)$$ -->\n\n- Space complexity:\n<!-- Add your space complexity here, e.g. $$O(n)$$ -->\n\n# Code\n```\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode() {}\n *     TreeNode(int val) { this.val = val; }\n *     TreeNode(int val, TreeNode left, TreeNode right) {\n *         this.val = val;\n *         this.left = left;\n *         this.right = right;\n *     }\n * }\n */\nclass Solution {\n    public int[] treeQueries(TreeNode root, int[] queries) {\n\n        //graph;\n        ArrayList<ArrayList<Integer>> adj = new ArrayList<>();\n        for(int i = 0; i <= 100000 + 5; i++) adj.add(new ArrayList<>());\n        Queue<TreeNode> q = new LinkedList<>();\n        q.offer(root);\n        while(!q.isEmpty()) {\n            int len = q.size();\n            for(int i = 0; i < len; i++) {\n                if(q.peek().left != null) {\n                    q.offer(q.peek().left);\n                    int u = q.peek().val;\n                    int v = q.peek().left.val;\n                    adj.get(u).add(v);\n                    adj.get(v).add(u);\n                }\n                if(q.peek().right != null) {\n                    q.offer(q.peek().right);\n                    int u = q.peek().val;\n                    int v = q.peek().right.val;\n                    adj.get(u).add(v);\n                    adj.get(v).add(u);\n                }\n                q.poll();\n            }\n        }\n\n        int depth[] = new int[100000 + 5];\n        ArrayList<Integer> flat = new ArrayList<>();\n        dfs(root.val,-1, adj, flat, depth);\n        \n\n        int len = flat.size();\n        int res[] = new int[len];\n        int first[] = new int[100000 + 1];\n        int last[] = new int[100000 + 1];\n        Arrays.fill(first, -1); Arrays.fill(last, -1);\n        for(int i = 0; i < len; i++) {\n            res[i] = depth[flat.get(i)];\n        }\n\n        for(int i = 0; i < flat.size(); i++) {\n            int current = flat.get(i);\n            if(first[current] == -1) first[current] = i;\n            else last[current] = i;\n        }\n\n\n       \n        int seg[] = new int[4 * len + 10];\n        build(res, seg, 0, 0, len - 1);\n\n        int ans[] = new int[queries.length];\n        for(int i = 0; i < queries.length; i++) {\n            int current = queries[i];\n            if(current == root.val) {\n                ans[i] = 0;\n                continue;\n            }\n            int x = query(res, seg, 0, 0, len - 1, 0 , first[current] - 1);\n            int y = query(res, seg , 0 , 0, len - 1, last[current] + 1, len - 1);\n            ans[i] = Math.max(x, y);\n\n\n        }\n        return ans;    \n    }\n\n    public static void dfs(int u , int par, ArrayList<ArrayList<Integer>> adj , ArrayList<Integer> flat,int depth[]) {\n        flat.add(u);\n        for(int v : adj.get(u)) {\n            if(v != par) {\n                depth[v] = 1 + depth[u];\n                dfs(v, u, adj, flat,depth);\n            }\n        }\n        flat.add(u);\n    }\n\n\n    //segment tree implementation;\n\n    public static void build(int arr[] , int seg[] , int ind, int low, int high) {\n        if(low == high) {\n            seg[ind] = arr[low];\n            return;\n        }\n        int mid = low + (high - low) / 2;\n        build(arr, seg, 2 * ind + 1, low, mid);\n        build(arr, seg, 2 * ind + 2, mid + 1, high);\n        seg[ind] = Math.max(seg[2 * ind + 1] , seg[2 * ind + 2]);\n    }\n\n    public static int query(int arr[] ,int seg[] , int ind, int low ,int high, int l , int r) {\n        if(low >= l && high <= r) return seg[ind];\n        if(low > r || high < l) return Integer.MIN_VALUE;\n        int mid = low + (high - low) / 2;\n        int left = query(arr, seg, 2 * ind + 1, low, mid, l , r);\n        int right = query(arr, seg, 2 * ind + 2, mid + 1, high, l , r);\n        return Math.max(left, right);\n    }\n}\n```
['Java']