线段树区间01区间值异或与相邻1个数

#include
using namespace std;
int tr[800000],l1[800000],r1[800000];
int l2[900000],r2[900000],tr2[800000];
int lazy[900000],a[200000];
void  pushup(int i,int l,int r)
{
    int mid=l+r>>1;
    r1[i]=r1[i*2+1];
    if(r1[i*2+1]==r-mid)
    {
        r1[i]+=r1[i*2];
    }
    l1[i]=l1[i*2];
    if(l1[i*2]==mid-l+1)
    {
        l1[i]+=l1[i*2+1];
    }
    tr[i]=max(tr[i*2],tr[i*2+1]);
    tr[i]=max(tr[i],r1[i*2]+l1[i*2+1]);
    r2[i]=r2[i*2+1];
    if(r2[i*2+1]==r-mid)
    {
        r2[i]+=r2[i*2];
    }
    l2[i]=l2[i*2];
    if(l2[i*2]==mid-l+1)
    {
        l2[i]+=l2[i*2+1];
    }
    tr2[i]=max(tr2[i*2],tr2[i*2+1]);
    tr2[i]=max(tr2[i],r2[i*2]+l2[i*2+1]);
}
void pushdown(int i)
{
    if(lazy[i]==1)
    {
        lazy[i]=0;
        lazy[i*2]^=1;
        lazy[i*2+1]^=1;
        swap(l1[i*2],l2[i*2]);
        swap(r1[i*2],r2[i*2]);
        swap(tr[i*2],tr2[i*2]);
        swap(l1[i*2+1],l2[i*2+1]);
        swap(r1[i*2+1],r2[i*2+1]);
        swap(tr[i*2+1],tr2[i*2+1]);
    }
}
void build(int i,int l,int r)
{
    lazy[i]=0;
    if(l==r)
    {
        l1[i]=r1[i]=tr[i]=a[l];
        if(a[l]==1)
            r2[i]=l2[i]=tr2[i]=0;
        else
            r2[i]=l2[i]=tr2[i]=1;
        return;
    }
    int mid=l+r>>1;
    build(i*2,l,mid);
    build(i*2+1,mid+1,r);
    pushup(i,l,r);
}
void update(int i,int l,int r,int x,int y)
{
    if(l==x&&r==y)
    {
        lazy[i]^=1;
        swap(l1[i],l2[i]);
        swap(r1[i],r2[i]);
        swap(tr[i],tr2[i]);
        return ;
    }
    pushdown(i);
    int mid=l+r>>1;
    if(y<=mid)
        update(i*2,l,mid,x,y);
    else if(x>mid)
        update(i*2+1,mid+1,r,x,y);
    else
    {
        update(i*2,l,mid,x,mid);
        update(i*2+1,mid+1,r,mid+1,y);
    }
    pushup(i,l,r);
}
int query(int i,int l,int r,int x,int y)
{
    if(x==l&&r==y)
    {
        return tr[i];
    }
    pushdown(i);
    int mid=l+r>>1;
    if(y<=mid)
        return query(i*2,l,mid,x,y);
    else if(x>mid)
        return query(i*2+1,mid+1,r,x,y);
    else
    {
        int aa,bb,cc;
        cc=min(mid-x+1,r1[i*2])+min(y-mid,l1[i*2+1]);
        aa=query(i*2,l,mid,x,mid);
        bb=query(i*2+1,mid+1,r,mid+1,y);
        return max(aa,max(bb,cc));
    }
}
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    build(1,1,n);
    int m;
    scanf("%d",&m);
    int op,x,y;
    while(m--)
    {
        scanf("%d%d%d",&op,&x,&y);
        if(op==1)
            update(1,1,n,x,y);
        else
            printf("%d\n",query(1,1,n,x,y));
    }
    return 0;
}

 

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