• UESTC1546 Bracket Sequence(区间覆盖&&区间合并)


    题目大意

    给定一个括号序列,支持一下以下三种操作:

    1、set l r c: 把区间 [l,r]内的所有元素全部改成 c(c是’(’或者’)’)
    2、reverse l r: 把区间[l,r]内的所以元素全部取反
    3、query l,r: 查询区间 [l,r] 括号序列是否合法

    题解

    把左括号当成-1,右括号当成1,如果括号序列合法,则区间和为0,并且任意前缀和会小于等于0,当然我们不需要判断所有的前缀和是否都小于等于0,只需要维护一个前缀和最大值即可,只要前缀和最大值小于等于0,并且区间和为0,括号序列就是合法的,为了处理方便还额外增加一个域,前缀和的最小值,在进行取反操作的时候会方便很多,另外要注意set和reverse两种操作的顺序,顺序不同,结果也就不同,如果是set操作,则之前所有的标记都失效了,直接清除即可,但是如果有 set标记则进行取反,否则进行异或标记的取反操作

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define lson l,m,s<<1
    #define rson m+1,r,s<<1|1
    #define MAXN 100005
    int setv[MAXN<<2],Xor[MAXN<<2],sumv[MAXN<<2],lmin[MAXN<<2],lmax[MAXN<<2];
    char str[MAXN];
    void PushUp(int s)
    {
            sumv[s]=sumv[s<<1]+sumv[s<<1|1];
            lmax[s]=max(lmax[s<<1],sumv[s<<1]+lmax[s<<1|1]);
            lmin[s]=min(lmin[s<<1],sumv[s<<1]+lmin[s<<1|1]);
    }
    void Fxor(int s,int m)
    {
            int temp;
            if(setv[s]!=0) {
                    if(setv[s]==1)
                            setv[s]=-1;
                    else
                            setv[s]=1;
                    if(setv[s]==1) {
                            sumv[s]=m;
                            lmax[s]=m;
                            lmin[s]=0;
                    } else {
                            sumv[s]=-m;
                            lmax[s]=0;
                            lmin[s]=-m;
                    }
            } else {
                    Xor[s]^=1;
                    sumv[s]=-sumv[s];
                    temp=lmax[s];
                    lmax[s]=-lmin[s];
                    lmin[s]=-temp;
            }
    }
    void PushDown(int s,int m)
    {
            if(setv[s]!=0) {
                    setv[s<<1]=setv[s<<1|1]=setv[s];
                    Xor[s<<1]=Xor[s<<1|1]=0;
                    if(setv[s]==1) {
                            sumv[s<<1]=(m-(m>>1));
                            sumv[s<<1|1]=(m>>1);
                            lmax[s<<1]=sumv[s<<1];
                            lmax[s<<1|1]=sumv[s<<1|1];
                            lmin[s<<1]=0;
                            lmin[s<<1|1]=0;
    
                    } else {
                            sumv[s<<1]=-(m-(m>>1));
                            sumv[s<<1|1]=-(m>>1);
                            lmin[s<<1]=-sumv[s<<1];
                            lmin[s<<1|1]=-sumv[s<<1|1];
                            lmax[s<<1]=0;
                            lmax[s<<1|1]=0;
                    }
                    setv[s]=0;
            }
            if(Xor[s]) {
                    Fxor(s<<1,m-(m>>1));
                    Fxor(s<<1|1,(m>>1));
                    Xor[s]=0;
            }
    }
    void build(int l,int r,int s)
    {
            setv[s]=0;
            Xor[s]=0;
            if(l==r) {
                    if(str[l]=='(')
                            sumv[s]=-1;
                    else
                            sumv[s]=1;
                    lmax[s]=(sumv[s]>0)?1:0;
                    lmin[s]=(sumv[s]<0)?-1:0;
                    return;
            }
            int m=(l+r)>>1;
            build(lson);
            build(rson);
            PushUp(s);
    }
    void update(int ql,int qr,int d,int l,int r,int s)
    {
            if(ql<=l&&r<=qr) {
                    if(d==-1) {
                            setv[s]=-1;
                            sumv[s]=-(r-l+1);
                            lmax[s]=0;
                            lmin[s]=sumv[s];
                            Xor[s]=0;
                    } else if(d==1) {
                            setv[s]=1;
                            sumv[s]=r-l+1;
                            lmax[s]=sumv[s];
                            lmin[s]=0;
                            Xor[s]=0;
                    } else
                            Fxor(s,r-l+1);
                    return;
            }
            PushDown(s,r-l+1);
            int m=(l+r)>>1;
            if(ql<=m) update(ql,qr,d,lson);
            if(qr>m) update(ql,qr,d,rson);
            PushUp(s);
    }
    int  querya(int ql,int qr,int l,int r,int s)
    {
            if(ql<=l&&r<=qr)
                    return sumv[s];
            PushDown(s,r-l+1);
            int m=(l+r)>>1,ans=0;
            if(ql<=m) ans+=querya(ql,qr,lson);
            if(qr>m) ans+=querya(ql,qr,rson);
            return ans;
    }
    int queryb(int ql,int qr,int l,int r,int s)
    {
            if(ql<=l&&r<=qr)
                    return lmax[s];
            PushDown(s,r-l+1);
            int m=(l+r)>>1,ans;
            if(qr<=m) ans=queryb(ql,qr,lson);
            else if(ql>m) ans=queryb(ql,qr,rson);
            else
                    ans=max(queryb(ql,qr,lson),querya(ql,qr,lson)+queryb(ql,qr,rson));
            return ans;
    }
    int main(void)
    {
            int T,n,m,a,b,p=0;
            char op[1000],ch[100];
            scanf("%d",&T);
            while(T--) {
                    printf("Case %d:\n",++p);
                    scanf("%d%s%d",&n,str,&m);
                    build(0,n-1,1);
                    while(m--) {
                            scanf("%s",op);
                            if(op[0]=='s') {
                                    scanf("%d%d%s",&a,&b,ch);
                                    if(ch[0]=='(')
                                            update(a,b,-1,0,n-1,1);
                                    else
                                            update(a,b,1,0,n-1,1);
                            } else if(op[0]=='r') {
                                    scanf("%d%d",&a,&b);
                                    update(a,b,2,0,n-1,1);
                            } else {
                                    scanf("%d%d",&a,&b);
                                    if(!querya(a,b,0,n-1,1)&&!queryb(a,b,0,n-1,1))
                                            printf("YES\n");
                                    else
                                            printf("NO\n");
                            }
                    }
                    printf("\n");
            }
            return 0;
    }

  • 相关阅读:
    JavaScript Date对象和函数 (一)
    Css3 文字渐变整理(一)
    Asp.net Core CacheHelper 通用缓存帮助类
    .net core中使用GB2312编码的问题
    苹果手机微信浏览器select标签选择完成之后页面不会自动回到原位
    .Net Core NOPI操作word(二) 表格操作
    .Net Core NOPI操作word(一)
    .NetCore中EFCore的使用整理(三)-关联表操作
    windos server2012安装.net core 2.2问题
    C# 最简单的使程序单进程运行的方法
  • 原文地址:https://www.cnblogs.com/zjbztianya/p/3114585.html
Copyright © 2020-2023  润新知