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;
}
原文地址:https://www.cnblogs.com/zjbztianya/p/3114594.html