// 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