• 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
    ",2*Tree.query(1,1,N,x,y).sum);
        }
        return 0;
    }
  • 相关阅读:
    听说你的MES系统又失败了?
    GROUP BY你都不会!ROLLUP,CUBE,GROUPPING详解
    对 MES 感兴趣?赶紧看过来!
    SQL 高级查询(层次化查询,递归)
    智能制造概念
    简单又实用的分享!SharePoint母版页引用(实战)
    原创分享!SharePoint母版页修改(实战)
    入门者必看!SharePoint之CAML总结(实战)
    新手必看!Office Web Apps 2013 安装与配置(实战)
    SharePoint布局页引用(实战)
  • 原文地址:https://www.cnblogs.com/hua-dong/p/8553449.html
Copyright © 2020-2023  润新知