Description
Sereja has a bracket sequence s1, s2, ..., sn, or, in other words, a string s of length n, consisting of characters "(" and ")".
Sereja needs to answer m queries, each of them is described by two integers li, ri(1 ≤ li ≤ ri ≤ n). The answer to the i-th query is the length of the maximum correct bracket subsequence of sequence sli, sli + 1, ..., sri. Help Sereja answer all queries.
You can find the definitions for a subsequence and a correct bracket sequence in the notes.
Input
The first line contains a sequence of characters s1, s2, ..., sn(1 ≤ n ≤ 106) without any spaces. Each character is either a "(" or a ")". The second line contains integer m(1 ≤ m ≤ 105) — the number of queries. Each of the next m lines contains a pair of integers. The i-th line contains integers li, ri(1 ≤ li ≤ ri ≤ n) — the description of the i-th query.
Output
Print the answer to each question on a single line. Print the answers in the order they go in the input.
Sample Input
())(())(())( 7 1 1 2 3 1 2 1 12 8 12 5 11 2 10
0 0 2 10 4 6 6
Hint
A subsequence of length |x| of string s = s1s2... s|s| (where |s| is the length of string s) is string x = sk1sk2... sk|x|(1 ≤ k1 < k2 < ... < k|x| ≤ |s|).
A correct bracket sequence is a bracket sequence that can be transformed into a correct aryphmetic expression by inserting characters "1" and "+" between the characters of the string. For example, bracket sequences "()()", "(())" are correct (the resulting expressions "(1)+(1)", "((1+1)+1)"), and ")(" and "(" are not.
For the third query required sequence will be «()».
For the fourth query required sequence will be «()(())(())».
#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAXN 1111111
using namespace std;
struct Node
{
int l,r,all;
Node()
{
l=r=all=0;
}
Node(int a,int b,int c)
{
l=a,r=b,all=c;
}
};
Node sum[MAXN<<2];
char str[MAXN];
void pushup(int rt)
{
int t=min(sum[rt<<1].l,sum[rt<<1|1].r);
sum[rt].all=sum[rt<<1].all+sum[rt<<1|1].all+t;
sum[rt].l=sum[rt<<1].l+sum[rt<<1|1].l-t;
sum[rt].r=sum[rt<<1].r+sum[rt<<1|1].r-t;
}
void build(int l,int r,int rt)
{
if(l==r)
{
if(str[l]=='(')
sum[rt].l++;
else if(str[l]==')')
sum[rt].r++;
return ;
}
int mid=(l+r)>>1;
build(l,mid,rt<<1);
build(mid+1,r,rt<<1|1);
pushup(rt);
}
Node query(int l,int r,int L,int R,int rt)
{
if(l>=L&&R>=r)
return sum[rt];
Node cnt1,cnt2;
int mid=(l+r)>>1;
if(L<=mid)
cnt1=query(l,mid,L,R,rt<<1);
if(R>mid)
cnt2=query(mid+1,r,L,R,rt<<1|1);
int t=min(cnt1.l,cnt2.r);
return Node(cnt1.l+cnt2.l-t,cnt1.r+cnt2.r-t,cnt1.all+cnt2.all+t);
}
int main()
{
int q,l,r;
scanf("%s",str+1);
scanf("%d",&q);
int n=strlen(str+1);
build(1,n,1);
while(q--)
{
scanf("%d %d",&l,&r);
printf("%d\n",2*query(1,n,l,r,1).all);
}
return 0;
}