class Node {
constructor() {
this
.maxPrefixSum = -Infinity;
this
.maxSuffixSum = -Infinity;
this
.totalSum = -Infinity;
this
.maxSubarraySum = -Infinity;
}
}
const inf = 0x3f3f;
function
merge(leftChild, rightChild) {
const parentNode =
new
Node();
parentNode.maxPrefixSum = Math.max(
leftChild.maxPrefixSum,
leftChild.totalSum + rightChild.maxPrefixSum
);
parentNode.maxSuffixSum = Math.max(
rightChild.maxSuffixSum,
rightChild.totalSum + leftChild.maxSuffixSum
);
parentNode.totalSum = leftChild.totalSum + rightChild.totalSum;
parentNode.maxSubarraySum = Math.max(
Math.max(
leftChild.maxSubarraySum,
rightChild.maxSubarraySum
),
leftChild.maxSuffixSum + rightChild.maxPrefixSum
);
return
parentNode;
}
function
constructTreeUtil(tree, arr, start, end, index) {
if
(start === end) {
tree[index].totalSum = arr[start];
tree[index].maxSuffixSum = arr[start];
tree[index].maxPrefixSum = arr[start];
tree[index].maxSubarraySum = arr[start];
return
;
}
const mid = Math.floor((start + end) / 2);
constructTreeUtil(tree, arr, start, mid, 2 * index);
constructTreeUtil(tree, arr, mid + 1, end, 2 * index + 1);
tree[index] = merge(tree[2 * index], tree[2 * index + 1]);
}
function
constructTree(arr, n) {
const x = Math.ceil(Math.log2(n));
const max_size = 2 * Math.pow(2, x) - 1;
const tree =
new
Array(max_size);
for
(let i = 0; i < max_size; i++)
tree[i] =
new
Node();
constructTreeUtil(tree, arr, 0, n - 1, 1);
return
tree;
}
function
queryUtil(tree, ss, se, qs, qe, index) {
if
(ss > qe || se < qs) {
const nullNode =
new
Node();
return
nullNode;
}
if
(qs <= ss && qe >= se) {
return
tree[index];
}
const mid = Math.floor((ss + se) / 2);
const leftChild = queryUtil(tree, ss, mid, qs, qe, 2 * index);
const rightChild = queryUtil(tree, mid + 1, se, qs, qe, 2 * index + 1);
return
merge(leftChild, rightChild);
}
function
query(tree, start, end, n) {
const res = queryUtil(tree, 0, n - 1, start, end, 1);
return
res.maxSubarraySum;
}
const arr = [1, 3, -4, 5, -2];
const n = arr.length;
const Tree = constructTree(arr, n);
let start, end, maxSubarraySum;
start = 0;
end = 4;
maxSubarraySum = query(Tree, start, end, n);
console.log(`Maximum Sub-Array Sum between ${start} and ${end} = ${maxSubarraySum} <br>`);
start = 0;
end = 2;
maxSubarraySum = query(Tree, start, end, n);
console.log(`Maximum Sub-Array Sum between ${start} and ${end} = ${maxSubarraySum}`);