// JavaScript program to find minimum and maximum using segment // tree // A utility function to get the middle index from corner // indexes. function getMid(s, e) { return Math.floor(s + (e - s) / 2); } // Node for storing minimum and maximum value of given range class Node { constructor(minimum, maximum) { this.minimum = minimum; this.maximum = maximum; } } /* A recursive function to get the minimum and maximum 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 */ function MaxMinUntill(st, ss, se, qs, qe, index) { // If segment of this node is a part of given range, // then return // the minimum and maximum node of the segment let tmp, left, right; if (qs <= ss && qe >= se) { return st[index]; } // If segment of this node is outside the given range if (se < qs || ss > qe) { tmp = new Node(Number.MAX_SAFE_INTEGER, Number.MIN_SAFE_INTEGER); return tmp; } // If a part of this segment overlaps with the given // range const mid = getMid(ss, se); left = MaxMinUntill(st, ss, mid, qs, qe, 2 * index + 1); right = MaxMinUntill(st, mid + 1, se, qs, qe, 2 * index + 2); tmp = new Node(Math.min(left.minimum, right.minimum), Math.max(left.maximum, right.maximum)); return tmp; } // Return minimum and maximum of elements in range from // index qs (query start) to qe (query end). It mainly uses // MaxMinUtill() function MaxMin(st, n, qs, qe) { let tmp; // Check for erroneous input values if (qs < 0 || qe > n - 1 || qs > qe) { console.log("Invalid Input"); tmp = new Node(Number.MAX_SAFE_INTEGER, Number.MIN_SAFE_INTEGER); return tmp; } return MaxMinUntill(st, 0, n - 1, qs, qe, 0); } // A recursive function that constructs Segment Tree for // array[ss..se]. si is index of current node in segment // tree st function constructSTUtil(arr, ss, se, st, si) { // If there is one element in array, store it in current // node of segment tree and return if (ss == se) { st[si] = new Node(arr[ss], arr[ss]); return; } // If there are more than one elements, then recur for // left and right subtrees and store the minimum and // maximum of two values in this node var mid = getMid(ss, se); constructSTUtil(arr, ss, mid, st, si * 2 + 1); constructSTUtil(arr, mid + 1, se, st, si * 2 + 2); st[si] = new Node(Math.min(st[si * 2 + 1].minimum, st[si * 2 + 2].minimum), Math.max(st[si * 2 + 1].maximum, st[si * 2 + 2].maximum)); } /* Function to construct segment tree from given array. This function allocates memory for segment tree and calls constructSTUtil() to fill the allocated memory */ function constructST(arr, n) { // Allocate memory for segment tree // Height of segment tree const x = Math.ceil(Math.log2(n)); // Maximum size of segment tree var max_size = 2 * Math.pow(2, x) - 1; var st = new Array(max_size).fill(null); // Fill the allocated memory st constructSTUtil(arr, 0, n - 1, st, 0); // Return the constructed segment tree return st; } // Driver code var arr = [1, 8, 5, 9, 6, 14, 2, 4, 3, 7]; var n = arr.length; // Build segment tree from given array var st = constructST(arr, n); var qs = 0; // Starting index of query range var qe = 8; // Ending index of query range var result = MaxMin(st, n, qs, qe); // Function call console.log(`Minimum = ${result.minimum} and Maximum = ${result.maximum}`); // This code is contributed by prasad264