HDU-3397-Sequence operation

       线段树区间操作题,我记录的东西比较多,其实题也不难,就是写起来麻烦,需要细心点。

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int inf=1<<29;
const int maxn=1e5+100;
const int maxm=maxn*3;
struct Node
{
    int l;
    int r;
    int len;
    int zero;
    int zerol;
    int zeror;
    int zerocnt;
    int one;
    int onel;
    int oner;
    int onecnt;
    bool isops;
}t[maxm];
int n,m,a[maxn];
void PushUp(int index)
{
    if(t[index<<1].zerol==t[index<<1].len)
        t[index].zerol=t[index<<1].len+t[index<<1|1].zerol;
    else
        t[index].zerol=t[index<<1].zerol;
    if(t[index<<1].onel==t[index<<1].len)
        t[index].onel=t[index<<1].len+t[index<<1|1].onel;
    else
        t[index].onel=t[index<<1].onel;
    if(t[index<<1|1].zeror==t[index<<1|1].len)
        t[index].zeror=t[index<<1|1].len+t[index<<1].zeror;
    else
        t[index].zeror=t[index<<1|1].zeror;
    if(t[index<<1|1].oner==t[index<<1|1].len)
        t[index].oner=t[index<<1|1].len+t[index<<1].oner;
    else
        t[index].oner=t[index<<1|1].oner;
    t[index].one=max(t[index<<1].one,t[index<<1|1].one);
    t[index].one=max(t[index].one,max(t[index].onel,t[index].oner));
    t[index].one=max(t[index].one,t[index<<1].oner+t[index<<1|1].onel);
    t[index].onecnt=t[index<<1].onecnt+t[index<<1|1].onecnt;
    t[index].zero=max(t[index<<1].zero,t[index<<1|1].zero);
    t[index].zero=max(t[index].zero,max(t[index].zerol,t[index].zeror));
    t[index].zero=max(t[index].zero,t[index<<1].zeror+t[index<<1|1].zerol);
    t[index].zerocnt=t[index<<1].zerocnt+t[index<<1|1].zerocnt;
}
void DealXOR(int index)
{
    swap(t[index].zero,t[index].one);
    swap(t[index].zerol,t[index].onel);
    swap(t[index].zeror,t[index].oner);
    swap(t[index].zerocnt,t[index].onecnt);
}
void PushDown(int index)
{
    if(t[index].l==t[index].r)
        return;
    if(t[index].isops)
    {
        t[index<<1].isops=1-t[index<<1].isops;
        t[index<<1|1].isops=1-t[index<<1|1].isops;
        DealXOR(index<<1);
        DealXOR(index<<1|1);
        t[index].isops=0;
    }
    if(!t[index].onecnt)
    {
        t[index<<1].isops=t[index<<1|1].isops=0;
        t[index<<1].one=t[index<<1].onel=t[index<<1].oner=t[index<<1].onecnt=0;
        t[index<<1].zero=t[index<<1].zerol=t[index<<1].zeror=t[index<<1].zerocnt=t[index<<1].len;
        t[index<<1|1].one=t[index<<1|1].onel=t[index<<1|1].oner=t[index<<1|1].onecnt=0;
        t[index<<1|1].zero=t[index<<1|1].zerol=t[index<<1|1].zeror=t[index<<1|1].zerocnt=t[index<<1|1].len;
    }
    if(!t[index].zerocnt)
    {
        t[index<<1].isops=t[index<<1|1].isops=0;
        t[index<<1].one=t[index<<1].onel=t[index<<1].oner=t[index<<1].onecnt=t[index<<1].len;
        t[index<<1].zero=t[index<<1].zerol=t[index<<1].zeror=t[index<<1].zerocnt=0;
        t[index<<1|1].one=t[index<<1|1].onel=t[index<<1|1].oner=t[index<<1|1].onecnt=t[index<<1|1].len;
        t[index<<1|1].zero=t[index<<1|1].zerol=t[index<<1|1].zeror=t[index<<1|1].zerocnt=0;
    }
}
void Build(int l,int r,int index)
{
    t[index].l=l;
    t[index].r=r;
    t[index].len=r-l+1;
    t[index].isops=false;
    if(l==r)
    {
        if(a[l])
        {
            t[index].one=t[index].onel=t[index].oner=t[index].onecnt=1;
            t[index].zero=t[index].zerol=t[index].zeror=t[index].zerocnt=0;
        }
        else
        {
            t[index].zero=t[index].zerol=t[index].zeror=t[index].zerocnt=1;
            t[index].one=t[index].onel=t[index].oner=t[index].onecnt=0;
        }
        return ;
    }
    int mid=(l+r)>>1;
    Build(l,mid,index<<1);
    Build(mid+1,r,index<<1|1);
    PushUp(index);
}

void Update(int l,int r,int index,int val)
{
    PushDown(index);
    if(t[index].l==l&&t[index].r==r)
    {
        if(val==0)
        {
            t[index].zerocnt=t[index].zero=t[index].zerol=t[index].zeror=t[index].len;
            t[index].onecnt=t[index].one=t[index].onel=t[index].oner=0;
            t[index].isops=0;
        }
        else if(val==1)
        {
            t[index].onecnt=t[index].one=t[index].onel=t[index].oner=t[index].len;
            t[index].zerocnt=t[index].zero=t[index].zerol=t[index].zeror=0;
            t[index].isops=0;
        }
        if(val==2)
        {
            DealXOR(index);
            t[index].isops=1;
        }
        return;
    }
    int mid=(t[index].l+t[index].r)>>1;
    if(l>mid)
        Update(l,r,index<<1|1,val);
    else if(r<=mid)
        Update(l,r,index<<1,val);
    else
    {
        Update(l,mid,index<<1,val);
        Update(mid+1,r,index<<1|1,val);
    }
    PushUp(index);
}

int Query(int l,int r,int index,int op)
{
    PushDown(index);
    if(t[index].l==l&&t[index].r==r)
    {
        if(op==0)
            return t[index].onecnt;
        else
            return t[index].one;
    }
    int mid=(t[index].l+t[index].r)>>1;
    int ans=0;
    if(r<=mid)
        ans=Query(l,r,index<<1,op);
    else if(l>mid)
        ans=Query(l,r,index<<1|1,op);
    else
    {
        if(op==0)
            ans=Query(l,mid,index<<1,op)+Query(mid+1,r,index<<1|1,op);
        else
        {
            ans=max(Query(l,mid,index<<1,op),Query(mid+1,r,index<<1|1,op));
            ans=max(ans,min(t[index<<1].oner,t[index<<1].r-l+1)+min(t[index<<1|1].onel,r-t[index<<1|1].l+1));
        }
    }
    PushUp(index);
    return ans;
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        Build(1,n,1);
        while(m--)
        {
            int op,sl,sr;
            scanf("%d%d%d",&op,&sl,&sr);
            sl++;
            sr++;
            if(op==0)
                Update(sl,sr,1,0);
            else if(op==1)
                Update(sl,sr,1,1);
            else if(op==2)
                Update(sl,sr,1,2);
            else if(op==3)
                printf("%d\n",Query(sl,sr,1,0));
            else
                printf("%d\n",Query(sl,sr,1,1));
        }
    }
    return 0;
}


你可能感兴趣的:(线段树)