Live2d Test Env

CodeForces-380C:Sereja and Brackets(线段树与括号序列)

 

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.

Example

Input
())(())(())(
7
1 1
2 3
1 2
1 12
8 12
5 11
2 10
Output
0
0
2
10
4
6
6

 题意:给定由‘(’和‘)’组成的字符串序列,然后Q个询问,每次回答区间最多有多少个匹配的括号。

 思路:分治的思想,当前的括号匹配对于左区间的匹配数+右区间的匹配数+min(左区间的未匹配的左括号,右区间的未匹配的右括号),同时改变当前区间未匹配的括号数。

注意:因为有3个参数需要传递,所以用结构体(因为要修改未匹配括号数)。

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=1000010;
char c[maxn];
struct in
{
    int a,b,sum;
    in(){ a=0; b=0; sum=0;}
}s[maxn<<2];
void read(int &res)
{
    char c=getchar();res=0; for(;c>'9'||c<'0';c=getchar());
    for(;c<='9'&&c>='0';c=getchar()) res=(res<<3)+(res<<1)+c-'0';
}

struct segment_tree
{
    void pushup(int Now)
    {
        int tmp=min(s[Now<<1].a,s[Now<<1|1].b);
        s[Now].sum=s[Now<<1].sum+s[Now<<1|1].sum+tmp;
        s[Now].a=s[Now<<1].a+s[Now<<1|1].a-tmp;
        s[Now].b=s[Now<<1].b+s[Now<<1|1].b-tmp;
    }
    void build(int Now,int L,int R)
    {
        if(L==R) {
           s[Now].a=(c[L]=='('?1:0);
           s[Now].b=(c[L]==')'?1:0);
           s[Now].sum=0; return ;
        }
        int Mid=(L+R)>>1;
        build(Now<<1,L,Mid);
        build(Now<<1|1,Mid+1,R);
        pushup(Now);
    }
    in query(int Now,int L,int R,int l,int r)
    {
        if(l<=L&&r>=R) return s[Now];
        int Mid=(L+R)>>1; in w,e,res;
        if(l<=Mid) w=query(Now<<1,L,Mid,l,r); 
        if(r>Mid) e=query(Now<<1|1,Mid+1,R,l,r);
        res.sum=min(w.a,e.b);
        res.a=w.a+e.a-res.sum;
        res.b=w.b+e.b-res.sum;
        res.sum+=w.sum+e.sum;
        return res;
    }
}Tree;
int main()
{
    int N,Q,x,y;
    scanf("%s",c+1);
    N=strlen(c+1);
    Tree.build(1,1,N);
    read(Q);
    while(Q--){
        read(x); read(y);
        printf("%d\n",2*Tree.query(1,1,N,x,y).sum);
    }
    return 0;
}

 

posted @ 2018-03-13 10:56  nimphy  阅读(483)  评论(0编辑  收藏  举报