<script>
// JavaScript program to implement
// the above approach
// Function to construct Segment Tree
// to return the minimum element in a range
function build(tree,A, start,end, node)
{
// If leaf nodes of
// the tree are found
if (start == end) {
// Update the value in segment
// tree from given array
tree[node] = A[start];
return tree[node];
}
// Divide left and right subtree
let mid = Math.floor((start + end) / 2);
// Stores smallest element in
// subarray { arr[start], arr[mid] }
let X = build(tree, A, start, mid,
2 * node + 1);
// Stores smallest element in
// subarray { arr[mid + 1], arr[end] }
let Y = build(tree, A, mid + 1,
end, 2 * node + 2);
// Stores smallest element in
// subarray { arr[start], arr[end] }
return tree[node] = Math.min(X, Y);
}
// Function to find the smallest
// element present in a subarray
function query(tree,start, end,l, r, node)
{
// If elements of the subarray
// are not in the range [l, r]
if (start > r || end < l)
return Number.MAX_VALUE;
// If all the elements of the
// subarray are in the range [l, r]
if (start >= l && end <= r)
return tree[node];
// Divide tree into left
// and right subtree
let mid = Math.floor((start + end) / 2);
// Stores smallest element
// in left subtree
let X = query(tree, start, mid, l,
r, 2 * node + 1);
// Stores smallest element in
// right subtree
let Y = query(tree, mid + 1, end, l,
r, 2 * node + 2);
return Math.min(X, Y);
}
// Function that find length of longest
// subarray with all equal elements in
// atmost K decrements
function longestSubArray(A,N,K)
{
// Stores length of longest subarray
// with all equal elements in atmost
// K decrements.
let res = 1;
// Store the prefix sum array
let preSum = new Array(N + 1);
// Calculate the prefix sum array
preSum[0] = A[0];
for (let i = 0; i < N; i++)
preSum[i + 1] = preSum[i] + A[i];
let tree = new Array(4 * N + 5);
// Build the segment tree
// for range min query
build(tree, A, 0, N - 1, 0);
// Traverse the array
for (let i = 0; i < N; i++) {
// Stores start index
// of the subarray
let start = i;
// Stores end index
// of the subarray
let end = N - 1;
let mid;
// Stores end index of
// the longest subarray
let max_index = i;
// Performing the binary search
// to find the endpoint
// for the selected range
while (start <= end) {
// Find the mid for binary search
mid = Math.floor((start + end) / 2);
// Find the smallest element in
// range [i, mid] using Segment Tree
let min_element
= query(tree, 0, N - 1, i, mid, 0);
// Stores total sum of subarray
// after K decrements
let expected_sum
= (mid - i + 1) * min_element;
// Stores sum of elements of
// subarray before K decrements
let actual_sum
= preSum[mid + 1] - preSum[i];
// If subarray found with
// all equal elements
if (actual_sum - expected_sum <= K) {
// Update start
start = mid + 1;
// Update max_index
max_index = Math.max(max_index, mid);
}
// If false, it means that
// the selected range is invalid
else {
// Update end
end = mid - 1;
}
}
// Store the length of longest subarray
res = Math.max(res, max_index - i + 1);
}
// Return result
return res;
}
// Driver Code
let arr = [ 1, 7, 3, 4, 5, 6 ];
let k = 6;
let n = 6;
document.write(longestSubArray(arr, n, k),"</br>");
// This code is contributed by shinjanpatra
</script>