不知道错哪里了全wa,路过dalao帮帮忙qwq

P2572 [SCOI2010] 序列操作

Link_Cut_Y @ 2021-09-04 14:14:46

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>

using namespace std;

const int N=100010;

struct SegmentTree
{
    int l,r;
    int sum;
    int lazy;
    int rev;
    int max[2];
    int l_max[2];
    int r_max[2];
}tr[N<<2];

int n,m;
int a[N];

void pushup(int u)
{
    tr[u].sum=tr[u<<1].sum+tr[u<<1|1].sum;

    for(int i=0;i<=1;i++)
    {
        tr[u].l_max[i]=tr[u<<1].l_max[i];

        if(i==1 && tr[u<<1].sum==tr[u<<1].r-tr[u<<1].l+1) tr[u].l_max[i]+=tr[u<<1|1].l_max[i];
        else if(i==0 && tr[u<<1].sum==0) tr[u].l_max[i]+=tr[u<<1|1].l_max[i];

        tr[u].r_max[i]=tr[u<<1].r_max[i];

        if(i==1 && tr[u<<1|1].sum==tr[u<<1|1].r-tr[u<<1|1].l+1) tr[u].r_max[i]+=tr[u<<1|1].r_max[i];
        else if(i==0 && tr[u<<1|1].sum==0) tr[u].r_max[i]+=tr[u<<1|1].r_max[i];

        auto &root=tr[u];
        auto &l=tr[u<<1];
        auto &r=tr[u<<1|1];

        root.max[i]=l.r_max[i]+r.l_max[i];
        root.max[i]=max(root.max[i],l.max[i]);
        root.max[i]=max(root.max[i],r.max[i]);
    }
}

void build(int u,int l,int r)
{
    auto &root=tr[u];

    tr[u]={l,r};
    tr[u].lazy=-1;

    if(l==r)
    {
        root.sum=a[l];
        root.max[0]=root.l_max[0]=root.r_max[0]=a[l]==0;
        root.max[1]=root.l_max[1]=root.r_max[1]=a[l]==1;
        return;
    }

    int mid=(l+r)>>1;
    build(u<<1,l,mid);
    build(u<<1|1,mid+1,r);

    pushup(u);
}

void pushdown(int u)
{
    auto &root=tr[u];
    auto &l=tr[u<<1];
    auto &r=tr[u<<1|1];

    if(root.lazy!=-1)
    {
        root.rev=0;
        int val=root.lazy;

        l.sum=(l.r-l.l+1)*val;
        r.sum=(r.r-r.l+1)*val;

        l.lazy=r.lazy=val;
        l.rev=r.rev=0;

        l.max[val]
        =l.l_max[val]
        =l.r_max[val]
        =l.r-l.l+1;

        l.max[val^1]
        =l.l_max[val^1]
        =r.r_max[val^1]
        =0;

        r.max[val]
        =r.l_max[val]
        =r.r_max[val]
        =r.r-r.l+1;

        r.max[val^1]
        =r.l_max[val^1]
        =r.r_max[val^1]
        =0;

        root.lazy=-1;
    }

    if(root.rev)
    {
        l.sum=(l.r-l.l+1)-l.sum;
        r.sum=(r.r-r.l+1)-r.sum;

        if(l.lazy!=-1) l.lazy^=1;
        else l.rev^=1;

        if(r.lazy!=-1) r.lazy^=1;
        else r.rev^=1;

        swap(l.max[0],l.max[1]);
        swap(l.l_max[0],l.l_max[1]);
        swap(l.r_max[0],l.r_max[1]);

        swap(r.max[0],r.max[1]);
        swap(r.l_max[0],r.l_max[1]);
        swap(r.r_max[0],r.r_max[1]);

        root.rev=0;
    }
}

void modify(int u,int val,int l,int r)
{
    pushdown(u);

    auto &root=tr[u];

    if(root.l==l && root.r==r)
    {
        if(val==0 || val==1)
        {
            root.sum=(root.r-root.l+1)*val;
            root.lazy=val;

            root.max[val]
            =root.l_max[val]
            =root.r_max[val]
            =root.r-root.l+1;

            root.max[val^1]
            =root.l_max[val^1]
            =root.r_max[val^1]
            =0;
        }

        else if(val==2)
        {
            root.sum=(root.r-root.l+1)-root.sum;
            root.rev^=1;

            swap(root.max[1],root.max[0]);
            swap(root.l_max[1],root.l_max[0]);
            swap(root.r_max[1],root.r_max[0]);
        }

        return;
    }

    int mid=(root.l+root.r)>>1;

    if(l>mid) modify(u<<1|1,val,l,r);
    else if(r<=mid) modify(u<<1,val,l,r);
    else modify(u<<1,val,l,mid),modify(u<<1|1,val,mid+1,r);

    pushup(u);
}

int query(int u,int l,int r)
{
    auto &root=tr[u];

    pushdown(u);

    if(root.l==l && root.r==r) return root.sum;
    int mid=(root.l+root.r)>>1;

    if(mid<l) return query(u<<1|1,l,r);
    else if(r<=mid) return query(u<<1,l,r);
    else return query(u<<1,l,mid)+query(u<<1|1,mid+1,r);
}

SegmentTree query_max(int u,int l,int r)
{
    auto &root=tr[u];

    pushdown(u);

    if(root.l==l && root.r==r) return root;

    int mid=(root.l+root.r)>>1;

    if(mid<l) return query_max(u<<1|1,l,r);
    else if(mid>=r) return query_max(u<<1,l,r);
    else
    {
        SegmentTree ret;
        SegmentTree ll=query_max(u<<1,l,mid),rr=query_max(u<<1|1,mid+1,r);
        ret.sum=ll.sum+rr.sum;

        for(int i=0;i<=1;i++)
        {
            ret.l_max[i]=ll.l_max[i];

            if(i==1 && ll.sum==ll.r-ll.l+1) ret.l_max[i]+=rr.l_max[i];
            else if(i==0 && ll.sum==0) ret.l_max[i]+=rr.l_max[i];;

            ret.r_max[i]=rr.r_max[i];

            if(i==1 && rr.sum==rr.r-rr.l+1) ret.r_max[i]+=ll.r_max[i];
            else if(i==0 && rr.sum==0) ret.r_max[i]+=ll.r_max[i];

            ret.max[i]=ll.r_max[i]+rr.l_max[i];
            ret.max[i]=max(ret.max[i],ll.max[i]);
            ret.max[i]=max(ret.max[i],rr.max[i]);
        }

        return ret;
    }
}

int main()
{
    scanf("%d%d",&n,&m);

    for(int i=1;i<=n;i++) scanf("%d",&a[i]);

    build(1,1,n);

    int opt,l,r;
    while(m--)
    {
        scanf("%d%d%d",&opt,&l,&r);
        l++,r++;

        if(opt==0) modify(1,0,l,r);
        else if(opt==1) modify(1,1,l,r);
        else if(opt==2) modify(1,2,l,r);
        else if(opt==3) printf("%d\n",query(1,l,r));
        else printf("%d\n",query_max(1,l,r).max[1]);
    }

    return 0;
}

|