```go
package main
import (
"bufio"
"fmt"
"os"
)
type Node struct {
l int
f byte
}
type SegTree struct {
n int
base int
t []Node
}
func combine(a, b Node) Node {
if a.l == 0 {
return b
}
if b.l == 0 {
return a
}
lastA := a.f ^ byte((a.l-1)&1)
if lastA == b.f {
if a.l == b.l {
return Node{}
}
if a.l > b.l {
return Node{l: a.l - b.l, f: a.f}
}
return Node{l: b.l - a.l, f: b.f ^ byte(a.l&1)}
}
return Node{l: a.l + b.l, f: a.f}
}
func NewSegTree(types []byte) *SegTree {
n := len(types)
base := 1
for base < n {
base <<= 1
}
t := make([]Node, base<<1)
for i := 0; i < n; i++ {
t[base+i] = Node{l: 1, f: types[i]}
}
for i := base - 1; i >= 1; i-- {
t[i] = combine(t[i<<1], t[i<<1|1])
}
return &SegTree{n: n, base: base, t: t}
}
func (st *SegTree) Query(l, r int) Node {
l += st.base
r += st.base
leftRes := Node{}
rightRes := Node{}
for l < r {
if (l & 1) == 1 {
leftRes = combine(leftRes, st.t[l])
l++
}
if (r & 1) == 1 {
r--
rightRes = combine(st.t[r], rightRes)
}
l >>= 1
r >>= 1
}
return combine(leftRes, rightRes)
}
type FastScanner struct {
r *bufio.Reader
}
func NewFastScanner() *FastScanner {
return &FastScanner{r: bufio.NewReaderSize(os.Stdin, 1<<20)}
}
func (fs *FastScanner) nextByte() (byte, error) {
return fs.r.ReadByte()
}
func (fs *FastScanner) skipSpaces() (byte, error) {
b, err := fs.r.ReadByte()
for err == nil && b <= ' ' {
b, err = fs.r.ReadByte()
}
return b, err
}
func (fs *FastScanner) NextInt() int {
b, err := fs.skipSpaces()
if err != nil {
return 0
}
sign := 1
if b == '-' {
sign = -1
b, _ = fs.r.ReadByte()
}
x := 0
for b >= '0' && b <= '9' {
x = x*10 + int(b-'0')
b, err = fs.r.ReadByte()
if err != nil {
break
}
}
return x * sign
}
func (fs *FastScanner) NextString() string {
b, err := fs.skipSpaces()
if err != nil {
return ""
}
buf := make([]byte, 0, 64)
for b > ' ' {
buf = append(buf, b)
b, err = fs.r.ReadByte()
if err != nil {
break
}
}
return string(buf)
}
func main() {
fs := NewFastScanner()
out := bufio.NewWriterSize(os.Stdout, 1<<20)
defer out.Flush()
t := fs.NextInt()
for ; t > 0; t-- {
s := fs.NextString()
n := len(s)
types := make([]byte, n)
for i := 0; i < n; i++ {
c := s[i]
if c == '(' || c == ')' {
types[i] = 1
} else {
types[i] = 0
}
}
st := NewSegTree(types)
q := fs.NextInt()
for i := 0; i < q; i++ {
l := fs.NextInt()
r := fs.NextInt()
res := st.Query(l-1, r)
fmt.Fprintln(out, res.l/2)
}
}
}
```