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;

}

你可能感兴趣的:(sequence)