#603(div 2)

603(div 2)

E .Editor

  • 题意: 输入一串字符串,由( ,), L,R 和其他字符组成。

  • 分析:

    • 首先要知道这几点,( 一 )对于括号匹配问题我们一般让左括号表示\(+1\) ,右括号表示\(-1\) 。这样如果前缀和为0表示左右括号都合理的匹配了。( 二 ) 跟据题意最后左右括号的最大嵌套数是所需的颜色数,由于从左向右先遇到左括号,一直+1.所以前缀和最大值为所需的颜色数。
    • 什么时候是 “ 很好 ” 的匹配?应该是所有的左右括号都有匹配,即任何一个前缀和都大于等与0,也就是 前缀和的最小值为0 。同时为了保证所有左右括号都匹配了,要求 第n个前缀和为0。 此时我们输出的结果是 前缀和最大值 。 不满足括号全部匹配就输出-1。
    • 那么由于在遍历字符串指行各种指令时会修改位置各个值,即动态修改然后问你结果。这就要用数据结构——线段树。本题需要维护三个值即上面加粗的三个值。
    • 这道题其实很好的作为线段树模板题。体现了线段数维护动态修改时的作用。很快会写一个关于线段树的博客。
  • 代码:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int MA=1e6+5;
    const int INF=0x3f3f3f3f;
    
    struct node
    {
        int l,r;
        int sum;
        int mx;
        int mn;
        int add;
    }tree[MA*4+5];
    
    void Pushup(int index)
    {
        tree[index].sum=tree[index<<1].sum+tree[index<<1|1].sum;
        tree[index].mx=max(tree[index<<1].mx,tree[index<<1|1].mx);
        tree[index].mn=min(tree[index<<1].mn,tree[index<<1|1].mn);
    }
    
    void Pushdown(int index)
    {
        if(tree[index].add){
            tree[index<<1].sum+=(tree[index<<1].r-tree[index<<1].l+1)*tree[index].add;
            tree[index<<1|1].sum+=(tree[index<<1|1].r-tree[index<<1|1].l+1)*tree[index].add;
            tree[index<<1].mx+=tree[index].add;
            tree[index<<1|1].mx+=tree[index].add;
            tree[index<<1].mn+=tree[index].add;
            tree[index<<1|1].mn+=tree[index].add;
            tree[index<<1].add+=tree[index].add;
            tree[index<<1|1].add+=tree[index].add;
            tree[index].add=0;
        }
    }
    
    void Build(int l,int r,int index)
    {
        tree[index].l=l;
        tree[index].r=r;
        tree[index].add=0;
        if(l==r){
            scanf("%d",&tree[index].sum);
            tree[index].mx=tree[index].mn=tree[index].sum;
    
            return ;
        }
        int mid=(l+r)>>1;
        Build(l,mid,index<<1);
        Build(mid+1,r,index<<1|1);
        Pushup(index);
    }
    
    void Updata(int l,int r,int index,int val)
    {
        if(l<=tree[index].l&&tree[index].r<=r){
           tree[index].sum+=(tree[index].r-tree[index].l+1)*val;
           tree[index].mx+=val;
           tree[index].mn+=val;
           tree[index].add+=val;
    
           return ;
        }
        Pushdown(index);
        int mid=(tree[index].l+tree[index].r)>>1;
        if(l<=mid) Updata(l,r,index<<1,val);
        if(mid<r) Updata(l,r,index<<1|1,val);
        Pushup(index);
    }
    
    int querySum(int l,int r,int index)
    {
       if(l<=tree[index].l&&tree[index].r<=r){
            return tree[index].sum;
       }
       Pushdown(index);
       int Sum=0;
       int Max=0;
       int Min=INF;
       int mid=(tree[index].l+tree[index].r)>>1;
       if(l<=mid) Sum+=querySum(l,r,index<<1);
       if(mid<r) Sum+=querySum(l,r,index<<1|1);
       return Sum;
    }
    
    int queryMx(int l,int r,int index)
    {
       if(l<=tree[index].l&&tree[index].r<=r){
            return tree[index].mx;
       }
       Pushdown(index);
       int Sum=0;
       int Max=0;
       int Min=INF;
       int mid=(tree[index].l+tree[index].r)>>1;
       if(l<=mid) Max=max(Max,queryMx(l,r,index<<1));
       if(mid<r) Max=max(Max,queryMx(l,r,index<<1|1));
       return Max;
    }
    
    
    int queryMn(int l,int r,int index)
    {
       if(l<=tree[index].l&&tree[index].r<=r){
            return tree[index].mn;
       }
       Pushdown(index);
       int Sum=0;
       int Max=0;
       int Min=INF;
       int mid=(tree[index].l+tree[index].r)>>1;
       if(l<=mid) Min=min(Min,queryMn(l,r,index<<1));
       if(mid<r) Min=min(Min,queryMn(l,r,index<<1|1));
       return Min;
    }
    
    string s;
    int ss[MA];
    int main()
    {
        int n;
        scanf("%d",&n);
        n=n+5;
        Build(1,n,1);
        cin>>s;
        int pos=1;
        vector<int>ans;
        for(int i=0;i<s.size();++i){
            if(s[i]=='('){
                Updata(pos,n,1,1-ss[pos]);
                ss[pos]=1;
            }
            else if(s[i]==')'){
                Updata(pos,n,1,-1-ss[pos]);
                ss[pos]=-1;
            }
            else if(s[i]=='L'){
                if(pos>1) pos--;
            }
            else if(s[i]=='R'){
                pos++;
            }
            else{
                if(ss[pos]==1){
                    Updata(pos,n,1,-1);
                }
                else if(ss[pos]==-1){
                    Updata(pos,n,1,1);
                }
                ss[pos]=0;
            }
    
            if(queryMn(1,n,1)==0&&querySum(n,n,1)==0){
                ans.push_back(queryMx(1,n,1));
            }
            else ans.push_back(-1);
        }
        for(int i=0;i<ans.size();++i){
            printf("%d ",ans[i]);
        }
        printf("\n");
        return 0;
    }
    
    
posted @ 2020-01-13 22:13  A_sc  阅读(108)  评论(0编辑  收藏  举报