// JavaScript code for the above approach
class Node {
constructor() {
this.value = 0;
this.max_set_bits = 0;
}
}
const tree = Array(4 * 10000).fill(null).map(() => new Node());
// Function that returns the count
// of set bits in a number
function setBits(x)
{
// Parity will store the
// count of set bits
let parity = 0;
while (x !== 0) {
if (x & 1) {
parity += 1;
}
x = x >> 1;
}
return parity;
}
// Function to build the segment tree
function buildSegmentTree(a, index, beg, end)
{
// Condition to check if there is
// only one element in the array
if (beg === end) {
tree[index].value = a[beg];
tree[index].maxSetBits = setBits(a[beg]);
} else {
const mid = Math.floor((beg + end) / 2);
// If there are more than one elements,
// then recur for left and right subtrees
buildSegmentTree(a, 2 * index + 1, beg, mid);
buildSegmentTree(a, 2 * index + 2, mid + 1, end);
// Condition to check the maximum set
// bits is greater in two subtrees
if (tree[2 * index + 1].maxSetBits > tree[2 * index + 2].maxSetBits) {
tree[index].maxSetBits = tree[2 * index + 1].maxSetBits;
tree[index].value = tree[2 * index + 1].value;
} else if (tree[2 * index + 2].maxSetBits > tree[2 * index + 1].maxSetBits) {
tree[index].maxSetBits = tree[2 * index + 2].maxSetBits;
tree[index].value = tree[2 * index + 2].value;
}
// Condition when maximum set bits
// are equal in both subtrees
else {
tree[index].maxSetBits = tree[2 * index + 2].maxSetBits;
tree[index].value = Math.max(
tree[2 * index + 2].value,
tree[2 * index + 1].value
);
}
}
}
// Function to do the range query
// in the segment tree
function query(index, beg, end, l, r) {
const result = { value: -1, maxSetBits: -1 };
// If segment of this node is outside the given
// range, then return the minimum value.
if (beg > r || end < l) {
return result;
}
// If segment of this node is a part of given
// range, then return the node of the segment
if (beg >= l && end <= r) {
return tree[index];
}
const mid = Math.floor((beg + end) / 2);
// If left segment of this node falls out of
// range, then recur in the right side of
// the tree
if (l > mid) {
return query(2 * index + 2, mid + 1, end, l, r);
}
// If right segment of this node falls out of
// range, then recur in the left side of
// the tree
if (r <= mid) {
return query(2 * index + 1, beg, mid, l, r);
}
// If a part of this segment overlaps with
// the given range
const left = query(2 * index + 1, beg, mid, l, r);
const right = query(2 * index + 2, mid + 1, end, l, r);
if (left.maxSetBits > right.maxSetBits) {
result.maxSetBits = left.maxSetBits;
result.value = left.value;
} else if (right.maxSetBits > left.maxSetBits) {
result.maxSetBits = right.maxSetBits;
result.value = right.value;
} else {
result.maxSetBits = right.maxSetBits;
result.value = Math.max(right.value, left.value);
}
return result;
}
// Driver code
const a = [18, 9, 8, 15, 14, 5];
buildSegmentTree(a, 0, 0, a.length - 1);
console.log(query(0, 0, a.length - 1, 1, 4).value+"<br>");
console.log(query(0, 0, a.length - 1, 0, 2).value);
// This code is contributed by Potta Lokesh.