Codeforces Round #223 (Div. 2) E Sereja and Brackets

来源:互联网 发布:nginx sub filter 编辑:程序博客网 时间:2024/05/20 03:40

【题意】给一个括号字符串,然后m个查询,查询【L,R】区间里最大的括号匹配数。

【解题方法】虽然是E题,但我不得不说这是个很水的题。我们只需要考虑一下每个区间没匹配左括号的个数,没匹配的右括号的个数,以及匹配的括号数即可。接下来就是区间合并的典型套路了。

【AC 代码】

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int maxn=1e6+10;char s[maxn];struct node{    int l,r;    int a,b,ans;}Tree[maxn<<2];void pushup(int rt){    int tt=min(Tree[rt*2].a,Tree[rt*2+1].b);    Tree[rt].a=Tree[rt*2].a+Tree[rt*2+1].a-tt;    Tree[rt].b=Tree[rt*2].b+Tree[rt*2+1].b-tt;    Tree[rt].ans=Tree[rt*2].ans+Tree[rt*2+1].ans+tt*2;}void Build(int l,int r,int rt){    Tree[rt].l=l,Tree[rt].r=r;    if(l==r){        if(s[l-1]=='(') Tree[rt].a++;        else Tree[rt].b++;        Tree[rt].ans=0;        return ;    }    int mid=(l+r)/2;    Build(l,mid,rt*2);    Build(mid+1,r,rt*2+1);    pushup(rt);}int ans,now;node queryans(int L,int R,int rt){    if(L==Tree[rt].l&&Tree[rt].r==R){        return Tree[rt];    }    int mid=(Tree[rt].l+Tree[rt].r)/2;    if(R<=mid) return queryans(L,R,rt*2);    else if(L>mid) return queryans(L,R,rt*2+1);    else{        node as;        node as1=queryans(L,mid,rt*2);        node as2=queryans(mid+1,R,rt*2+1);        int tt=min(as1.a,as2.b);        as.a=as1.a+as2.a-tt;        as.b=as1.b+as2.b-tt;        as.ans=as1.ans+as2.ans+tt*2;        return as;    }}int main(){    cin>>s;    int n=strlen(s);    Build(1,n,1);    int q,l,r;    cin>>q;    for(int i=1; i<=q; i++){        cin>>l>>r;        node tmp=queryans(l,r,1);        cout<<tmp.ans<<endl;    }}


0 0
原创粉丝点击