// C# implementation of the above approach.
using System;
class GFG
{
// Segment tree
static int[] tree_min = new int[1000001];
static int[] tree_max = new int[1000001];
// Functions to return
// minimum and maximum
static int min(int a, int b)
{
return a < b ? a : b;
}
static int max(int a, int b)
{
return a > b ? a : b;
}
// Segment tree for minimum element
static void build_min(int []array, int node,
int left, int right)
{
// If left is equal to right
if (left == right)
tree_min[node] = array[left];
else
{
// Divide the segment into equal halves
build_min(array, 2 * node, left, (left + right) / 2);
build_min(array, 2 * node + 1,
(left + right) / 2 + 1, right);
// Update the element as minimum
// of the divided two subarrays
tree_min[node] = Math.Min(tree_min[2 * node],
tree_min[2 * node + 1]);
}
}
// Query to find a minimum
// in a given ranges
static int query_min(int node, int c_l,
int c_r, int l, int r)
{
// Out of range
if (c_l > r || c_r < l)
return (int) 1e9;
// Within the range completely
if (c_l >= l && c_r <= r)
return tree_min[node];
else
// Divide the range into two halves
// Query for each half
// and return the minimum of two
return min(query_min(2 * node, c_l,
(c_l + c_r) / 2, l, r),
query_min(2 * node + 1,
(c_l + c_r) / 2 + 1, c_r, l, r));
}
// Segment tree for maximum element
static void build_max(int []array, int node,
int left, int right)
{
// If left is equal to right
if (left == right)
tree_max[node] = array[left];
else
{
// Divide the segment into equal halves
build_max(array, 2 * node, left, (left + right) / 2);
build_max(array, 2 * node + 1, (left + right) / 2 + 1, right);
// Update the element as maximum
// of the divided two subarrays
tree_max[node] = Math.Max(tree_max[2 * node],
tree_max[2 * node + 1]);
}
}
// Query to find maximum
// in a given ranges
static int query_max(int node, int c_l,
int c_r, int l, int r)
{
// Out of range
if (c_l > r || c_r < l)
return -1;
// Within the range completely
if (c_l >= l && c_r <= r)
return tree_max[node];
else
// Divide the range into two halves
// and query for each half
// and return the maximum of two
return Math.Max(query_max(2 * node, c_l,
(c_l + c_r) / 2, l, r),
query_max(2 * node + 1,
(c_l + c_r) / 2 + 1, c_r, l, r));
}
// Build the tree
static void init(int []array, int n)
{
build_min(array, 1, 0, n - 1);
build_max(array, 1, 0, n - 1);
}
// Check if the given range is Consecutive
static bool isConsecutive(int x, int y, int n)
{
return ((query_max(1, 0, n - 1, x, y) -
query_min(1, 0, n - 1, x, y)) == (y - x));
}
// Driver code
public static void Main(String[] args)
{
int []arr = {2, 4, 3, 7, 6, 1};
int [,]query = {{ 1, 3 }, { 3, 5 }, { 5, 6 }};
int n = arr.Length, q = 3;
init(arr, n);
for (int i = 0; i < q; i++)
{
int l, r;
l = query[i,0];
r = query[i,1];
Console.Write((isConsecutive(l - 1, r - 1, n) ?
"Yes" : "No") + "\n");
}
}
}
// This code is contributed by Rajput-Ji