// C# Program to implement // the above approach using System; class GFG { // Function to obtain the // middle index of the range static int getMid(int s, int e) { return s + (e - s) / 2; } /* Recursive function to get the sum of values in the given range from the array. The following are parameters for this function: st--> Pointer to segment tree node--> Index of current node in segment tree ss & se--> Starting and ending indexes of the segment represented by current node, i.e., st[node] l & r--> Starting and ending indexes of range query */ static int MaxUtil(int[] st, int ss, int se, int l, int r, int node) { // If the segment of this node lies // completely within the given range if (l <= ss && r >= se) // Return maximum in the segment return st[node]; // If the segment of this node lies // outside the given range if (se < l || ss > r) return -1; // If segment of this node lies // partially in the given range int mid = getMid(ss, se); return Math.Max( MaxUtil(st, ss, mid, l, r, 2 * node + 1), MaxUtil(st, mid + 1, se, l, r, 2 * node + 2)); } // Function to return the maximum // in the range from [l, r] static int getMax(int[] st, int n, int l, int r) { // Check for erroneous input values if (l < 0 || r > n - 1 || l > r) { Console.Write("Invalid Input"); return -1; } return MaxUtil(st, 0, n - 1, l, r, 0); } // Function to construct Segment Tree // for the subarray [ss..se] static int constructSTUtil(int[] arr, int ss, int se, int[] st, int si) { // For a single element if (ss == se) { st[si] = arr[ss]; return arr[ss]; } // Otherwise int mid = getMid(ss, se); // Recur for left subtree st[si] = Math.Max( constructSTUtil(arr, ss, mid, st, si * 2 + 1), // Recur for right subtree constructSTUtil(arr, mid + 1, se, st, si * 2 + 2)); return st[si]; } // Function to construct Segment Tree // from the given array static int[] constructST(int[] arr, int n) { // Height of Segment Tree int x = (int)(Math.Ceiling(Math.Log(n))); // Maximum size of Segment Tree int max_size = 2 * (int)Math.Pow(2, x) - 1; // Allocate memory int[] st = new int[max_size]; // Fill the allocated memory constructSTUtil(arr, 0, n - 1, st, 0); // Return the constructed Segment Tree return st; } // Driver Code public static void Main(String[] args) { int[] arr = {5, 2, 3, 0}; int n = arr.Length; // Build the Segment Tree // from the given array int[] st = constructST(arr, n); int[, ] Q = {{1, 3}, {0, 2}}; for (int i = 0; i < Q.GetLength(0); i++) { int max = getMax(st, n, Q[i, 0], Q[i, 1]); int ok = 0; for (int j = 30; j >= 0; j--) { if ((max & (1 << j)) != 0) ok = 1; if (ok <= 0) continue; max |= (1 << j); } Console.Write(max + " "); } } } // This code is contributed by Amit Katiyar