function
node() {
this
.t = 0;
this
.o = 0;
this
.c = 0;
}
let tree_arr =
new
Array(5 * 1000);
function
build(id, l, r, s)
{
if
(r - l < 2) {
if
(s[l] == '(
')
tree_arr[id].o = 1;
// If that element is open bracket
else
tree_arr[id].c = 1;
return;
}
// Next three lines are common
// for any segment tree.
let mid = Math.floor((l + r) / 2);
// for left tree
build(2 * id, l, mid, s);
// for right tree
build(2 * id + 1, mid, r, s);
// Here we take minimum of left tree
// opening brackets and right tree
// closing brackets
let tmp = Math.min(tree_arr[2 * id].o,
tree_arr[2 * id + 1].c);
// we add that to our answer.
tree_arr[id].t = tree_arr[2 * id].t +
tree_arr[2 * id + 1].t + tmp;
// Remove the answer from opening brackets
tree_arr[id].o = tree_arr[2 * id].o +
tree_arr[2 * id + 1].o - tmp;
// Remove the answer from opening brackets
tree_arr[id].c = tree_arr[2 * id].c +
tree_arr[2 * id + 1].c - tmp;
}
// This will return the answer for each query.
// Here we consider query'
s interval as [x, y)
function
segment(x, y, id,
l, r, s)
{
if
(l >= y || x >= r) {
let tem =
new
node();
return
tem;
}
if
(x <= l && r <= y)
return
tree_arr[id];
let mid = Math.floor((l + r) / 2);
let a =
segment(x, y, 2 * id, l, mid, s);
let b =
segment(x, y, 2 * id + 1, mid, r, s);
let temp;
temp = Math.min(a.o, b.c);
let vis =
new
node();
vis.t = a.t + b.t + temp;
vis.o = a.o + b.o - temp;
vis.c = a.c + b.c - temp;
return
vis;
}
function
main()
{
let s =
"((())(()"
;
let n = s.length;
let a = 3, b = 8;
build(1, 0, n, s);
let p = segment(a-1, b, 1, 0, n, s);
console.log(p.t);
return
0;
}
main();