hdu 3997 Sequence operation 线段树 3997

这几题基本一样啊

hdu 3911

hdu 3997

POJ 2892

#include<cstdio>
#include<cstring>
#define left l,m,x<<1
#define right m+1,r,x<<1|1
const int LMT=100005;
int ox[LMT<<2],cov[LMT<<2],lsum[2][LMT<<2],msum[2][LMT<<2],rsum[2][LMT<<2],sum[2][LMT<<2];
inline int max(int a,int b)
{
    return a>b?a:b;
}
void init(void)
{
    memset(ox,0,sizeof(ox));
    memset(cov,0,sizeof(cov));
    memset(lsum,0,sizeof(lsum));
    memset(msum,0,sizeof(msum));
    memset(rsum,0,sizeof(rsum));
    memset(sum,0,sizeof(sum));
}
void ope(int op,int l,int r,int x)
{
    cov[x]=op;
    lsum[op][x]=rsum[op][x]=msum[op][x]
        =sum[op][x]=(r-l+1);
    lsum[!op][x]=rsum[!op][x]=msum[!op][x]
        =sum[!op][x]=0;
    ox[x]=0;
}
void swap(int &a,int &b)
{
    int t=a;
    a=b;
    b=t;
}
void fox(int l,int r,int x)
{
    if(cov[x]!=-1)cov[x]^=1;
    else ox[x]^=1;
        swap(lsum[0][x],lsum[1][x]);
        swap(rsum[0][x],rsum[1][x]);
        swap(msum[0][x],msum[1][x]);
        swap(sum[0][x],sum[1][x]);
}
void cut(int l,int r,int x)
{
    int m=(l+r)>>1;
    if(cov[x]!=-1)
    {
        ope(cov[x],left);ope(cov[x],right);
        cov[x]=-1;
    }
    if(ox[x])
    {
        fox(left);fox(right);
        ox[x]=0;
    }
}
void pushup(int op,int x,int len)
{
    lsum[op][x]=lsum[op][x<<1];
    rsum[op][x]=rsum[op][x<<1|1];
    if(lsum[op][x]==len-(len>>1))
        lsum[op][x]+=lsum[op][x<<1|1];
    if(rsum[op][x]==len>>1)
        rsum[op][x]+=rsum[op][x<<1];
    msum[op][x]=max(lsum[op][x<<1|1]+rsum[op][x<<1],max(msum[op][x<<1],msum[op][x<<1|1]));
    sum[op][x]=sum[op][x<<1]+sum[op][x<<1|1];
}
void update(int op,int L,int R,int l,int r,int x)
{
    if(L<=l&&r<=R)
    {
        if(op==0)
            ope(0,l,r,x);
        if(op==1)
            ope(1,l,r,x);
        if(op==2)fox(l,r,x);
        return;
    }
    cut(l,r,x);
    int m=(l+r)>>1;
    if(L<=m)update(op,L,R,left);
    if(R>m)update(op,L,R,right);
    pushup(1,x,r-l+1);
    pushup(0,x,r-l+1);
}
int query1(int L,int R,int l,int r,int x)
{
    if(L<=l&&r<=R)return sum[1][x];
    cut(l,r,x);
    int m=(l+r)>>1,res=0;
    if(L<=m)res+=query1(L,R,left);
    if(R>m)res+=query1(L,R,right);
    return res;
}
void query2(int have[],int L,int R,int l,int r,int x)
{
    if(L<=l&&r<=R)
    {
        have[0]=lsum[1][x];
        have[1]=msum[1][x];
        have[2]=rsum[1][x];
        return;
    }
    cut(l,r,x);
    int ha1[3],ha2[3],m=(l+r)>>1,len=r-l+1;
    memset(ha1,0,sizeof(ha1));
    memset(ha2,0,sizeof(ha2));
    if(L<=m)query2(ha1,L,R,left);
    if(R>m)query2(ha2,L,R,right);
    have[0]=ha1[0];have[2]=ha2[2];
    if(have[0]==len-(len>>1))have[0]+=ha2[0];
    if(have[2]==len>>1)have[2]+=ha1[2];
    have[1]=max(ha1[2]+ha2[0],max(ha1[1],ha2[1]));
}
int main(void)
{
    int i,x,T,n,m,l,r,op,have[3];
    scanf("%d",&T);
    while(T--)
    {
                init();
        scanf("%d%d",&n,&m);
        for(i=0;i<n;i++)
        {
            scanf("%d",&x);
            update(x,i,i,0,n-1,1);
        }
        while(m--)
        {
            scanf("%d%d%d",&op,&l,&r);
            switch(op)
            {
            case 0:update(op,l,r,0,n-1,1);break;
            case 1:update(op,l,r,0,n-1,1);break;
            case 2:update(op,l,r,0,n-1,1);break;
            case 3:printf("%d\n",query1(l,r,0,n-1,1));break;
            case 4:
                memset(have,0,sizeof(have));
                query2(have,l,r,0,n-1,1);
                printf("%d\n",have[1]);
                break;
            }
        }
    }
    return 0;
}


你可能感兴趣的:(hdu 3997 Sequence operation 线段树 3997)