class Node {
constructor(l, r) {
this.l = l;
this.r = r;
this.mid = (l + r) >> 1;
this.left = null;
this.right = null;
this.v = 0;
this.add = 0; // lazy sign
}
};
class SegmentTree {
constructor() {
this.root = new Node(1, 1e9);
}
update_inside(l, r, v, node) {
if (l > r)
return;
if (node.l >= l && node.r <= r) {
node.v = v;
node.add = v;
return;
}
this.pushdown(node);
if (l <= node.mid)
this.update_inside(l, r, v, node.left);
if (r > node.mid)
this.update_inside(l, r, v, node.right);
this.pushup(node);
}
update(l, r, v) {
this.update_inside(l, r, v, this.root);
}
query_inside(l, r, node) {
if (l > r)
return 0;
if (node.l >= l && node.r <= r) //the node is covered by the area
return node.v;
this.pushdown(node);
let v = 0;
if (l <= node.mid)
v = Math.max(v, this.query_inside(l, r, node.left));
if (r > node.mid)
v = Math.max(v, this.query_inside(l, r, node.right));
return v;
}
query(l, r) {
return this.query_inside(l, r, this.root);
}
pushup(node) {
node.v = Math.max(node.left.v, node.right.v);
}
pushdown(node) {
if (!node.left)
node.left = new Node(node.l, node.mid);
if (!node.right)
node.right = new Node(node.mid + 1, node.r);
if (node.add) {
let left = node.left;
let right = node.right;
left.v = node.add;
right.v = node.add;
left.add = node.add;
right.add = node.add;
node.add = 0;
}
}
};