• HDU3397 Sequence operation(区间更新&&区间合并)


    题目大意

    给定一个长度为n的01序列,可以对其进行以下五种操作:
    1、0 a b 把区间 [a , b]内的所有元素全部变为0
    2、1 a b 把区间 [a , b]内的所有元素全部变为1
    3、2 a b 把区间 [a, b]内的所以元素进行取反操作
    4、3 a b 查询 区间[a, b]内元素1的总数
    5、4 a b 查询区间 [a , b]的元素为1的最长连续子序列长度

    题解

    区间更新和区间合并的综合题。。。。细心点就行。。。。

    代码:

    #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];
    int sumv[MAXN<<2],lsum[MAXN<<2];
    int rsum[MAXN<<2],msum[MAXN<<2];
    int tlsum[MAXN<<2],trsum[MAXN<<2],tmsum[MAXN<<2];
    void Fxor(int s,int m)
    {
            if(setv[s]!=-1) {
                    setv[s]^=1;
                    sumv[s]=lsum[s]=rsum[s]=msum[s]=setv[s]?m:0;
                    tlsum[s]=trsum[s]=tmsum[s]=setv[s]?0:m;
            } else {
                    Xor[s]^=1;
                    sumv[s]=m-sumv[s];
                    swap(lsum[s],tlsum[s]);
                    swap(rsum[s],trsum[s]);
                    swap(msum[s],tmsum[s]);
            }
    }
    void PushUp(int s,int m)
    {
            sumv[s]=sumv[s<<1]+sumv[s<<1|1];
            lsum[s]=lsum[s<<1];
            rsum[s]=rsum[s<<1|1];
            tlsum[s]=tlsum[s<<1];
            trsum[s]=trsum[s<<1|1];
            msum[s]=max(msum[s<<1],msum[s<<1|1]);
            tmsum[s]=max(tmsum[s<<1],tmsum[s<<1|1]);
            if(lsum[s<<1]==(m-(m>>1)))lsum[s]+=lsum[s<<1|1];
            if(rsum[s<<1|1]==(m>>1)) rsum[s]+=rsum[s<<1];
            msum[s]=max(msum[s],rsum[s<<1]+lsum[s<<1|1]);
            if(tlsum[s<<1]==(m-(m>>1))) tlsum[s]+=tlsum[s<<1|1];
            if(trsum[s<<1|1]==(m>>1)) trsum[s]+=trsum[s<<1];
            tmsum[s]=max(tmsum[s],trsum[s<<1]+tlsum[s<<1|1]);
    }
    void PushDown(int s,int m)
    {
            if(setv[s]!=-1) {
                    setv[s<<1]=setv[s<<1|1]=setv[s];
                    if(setv[s]==0) {
                            sumv[s<<1]=lsum[s<<1]=rsum[s<<1]=msum[s<<1]=0;
                            sumv[s<<1|1]=lsum[s<<1|1]=rsum[s<<1|1]=msum[s<<1|1]=0;
                            tlsum[s<<1]=trsum[s<<1]=tmsum[s<<1]=(m-(m>>1));
                            tlsum[s<<1|1]=trsum[s<<1|1]=tmsum[s<<1|1]=(m>>1);
                    } else {
                            sumv[s<<1]=lsum[s<<1]=rsum[s<<1]=msum[s<<1]=(m-(m>>1));
                            sumv[s<<1|1]=lsum[s<<1|1]=rsum[s<<1|1]=msum[s<<1|1]=(m>>1);
                            tlsum[s<<1]=trsum[s<<1]=tmsum[s<<1]=0;
                            tlsum[s<<1|1]=trsum[s<<1|1]=tmsum[s<<1|1]=0;
                    }
                    setv[s]=-1;
                    Xor[s<<1]=Xor[s<<1|1]=0;
            }
            if(Xor[s]==1) {
                    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]=-1;
            Xor[s]=0;
            if(l==r) {
                    scanf("%d",&sumv[s]);
                    tmsum[s]=tlsum[s]=trsum[s]=sumv[s]?0:1;
                    msum[s]=lsum[s]=rsum[s]=sumv[s];
                    return;
            }
            int m=(l+r)>>1;
            build(lson);
            build(rson);
            PushUp(s,r-l+1);
    }
    void update(int ql,int qr,int d,int l,int r,int s)
    {
            if(ql<=l&&r<=qr) {
    
                    if(d==0) {
                            msum[s]=lsum[s]=rsum[s]=sumv[s]=0;
                            tmsum[s]=tlsum[s]=trsum[s]=r-l+1;
                            setv[s]=0;
                            Xor[s]=0;
                    } else if(d==1) {
                            msum[s]=lsum[s]=rsum[s]=sumv[s]=r-l+1;
                            tmsum[s]=tlsum[s]=trsum[s]=0;
                            setv[s]=1;
                            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,r-l+1);
    }
    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 msum[s];
            PushDown(s,r-l+1);
            int m=(l+r)>>1,ans=0;
            if(ql<=m) ans=max(ans,queryb(ql,qr,lson));
            if(qr>m) ans=max(ans,queryb(ql,qr,rson));
            ans=max(ans,min(qr,m+lsum[s<<1|1])-max(ql,m-rsum[s<<1]+1)+1);
            return ans;
    }
    int main(void)
    {
            int n,m,T,op,a,b;
            scanf("%d",&T);
            while(T--) {
                    scanf("%d%d",&n,&m);
                    build(0,n-1,1);
                    while(m--) {
                            scanf("%d%d%d",&op,&a,&b);
                            if(op==0||op==1||op==2)
                                    update(a,b,op,0,n-1,1);
                            else if(op==3)
                                    printf("%d\n",querya(a,b,0,n-1,1));
                            else
                                    printf("%d\n",queryb(a,b,0,n-1,1));
                    }
            }
            return 0;
    }
  • 相关阅读:
    KDJ回测
    利用网易获取所有股票数据
    利用东方财富网获取股票代码
    python发邮件
    用指针向数组插入元素
    冒泡排序
    Hadoop的安装与配置
    关于执行memcached报错问题
    tomcat Linux安装
    网易CentOS yum源
  • 原文地址:https://www.cnblogs.com/zjbztianya/p/3114594.html
Copyright © 2020-2023  润新知