MnZn求助,只过#11,其余全WA

P2572 [SCOI2010] 序列操作

EastIsRed @ 2023-12-06 17:15:23

#include<cstdio>
#include<algorithm>
using namespace std;
int n,m,a[100086];
struct node{
    int l,r;
    struct message{
        int sum,l_len,r_len,m_len;
        message():sum(0),l_len(0),r_len(0),m_len(0){}
        message(int _sum,int _l_len,int _r_len,int _m_len):sum(_sum),l_len(_l_len),r_len(_r_len),m_len(_m_len){}
        message(const message& rhs):sum(rhs.sum),l_len(rhs.l_len),r_len(rhs.r_len),m_len(rhs.m_len){}
        void set(int val=0)
        {
            sum=l_len=r_len=m_len=val;
        }
    }mess[2];
    int lzd1,lzd2;
}tr[400086];
inline node::message merge_mess(const node::message& a,const node::message& b,int lenl,int lenr)
{
    return node::message(a.sum+b.sum,a.l_len==lenl?lenl+b.l_len:a.l_len,b.r_len==lenr?a.r_len+lenr:b.r_len,max({a.m_len,b.m_len,a.r_len+b.l_len}));
}
inline void push_up(int now)
{
    int mid=tr[now].l+tr[now].r>>1;
    tr[now].mess[0]=merge_mess(tr[now<<1].mess[0],tr[now<<1|1].mess[0],mid-tr[now].l+1,tr[now].r-mid);
    tr[now].mess[1]=merge_mess(tr[now<<1].mess[1],tr[now<<1|1].mess[1],mid-tr[now].l+1,tr[now].r-mid);
}
void build(int now,int l,int r)
{
    tr[now].l=l;
    tr[now].r=r;
    tr[now].lzd1=-1;
    tr[now].lzd2=0;
    if(l!=r)
    {
        int mid=l+r>>1;
        build(now<<1,l,mid);
        build(now<<1|1,mid+1,r);
        push_up(now);
    }
    else tr[now].mess[a[l]].set(1),tr[now].mess[a[l]^1].set();
}
inline void lzd_down(int now)
{
    if(tr[now].lzd1!=-1)
    {
        tr[now<<1].mess[tr[now].lzd1].set(tr[now<<1].r-tr[now<<1].l+1);
        tr[now<<1].mess[tr[now].lzd1^1].set();
        tr[now<<1|1].mess[tr[now].lzd1].set(tr[now<<1|1].r-tr[now<<1|1].l+1);
        tr[now<<1|1].mess[tr[now].lzd1^1].set();
        tr[now<<1].lzd1=tr[now<<1|1].lzd1=tr[now].lzd1;
        tr[now<<1].lzd2=tr[now<<1|1].lzd2=0;
        tr[now].lzd1=-1;
    }
    if(tr[now].lzd2)
    {
        swap(tr[now<<1].mess[0],tr[now<<1].mess[1]);
        swap(tr[now<<1|1].mess[0],tr[now<<1|1].mess[1]);
        tr[now].lzd2=0;
        if(tr[now<<1].lzd1!=-1)
            tr[now<<1].lzd1^=1;
        else tr[now<<1].lzd2^=1;
        if(tr[now<<1|1].lzd1!=-1)
            tr[now<<1|1].lzd1^=1;
        else tr[now<<1|1].lzd2^=1;
    }
}
void change(int now,int l,int r,int val)
{
    if(l<=tr[now].l&&tr[now].r<=r)
    {
        tr[now].mess[val].set(tr[now].r-tr[now].l+1);
        tr[now].mess[val^1].set();
        tr[now].lzd1=val;
        tr[now].lzd2=0;
        return;
    }
    int mid=tr[now].l+tr[now].r>>1;
    lzd_down(now);
    if(l<=mid)
        change(now<<1,l,r,val);
    if(mid<r)
        change(now<<1|1,l,r,val);
    push_up(now);
}
void reverse(int now,int l,int r)
{
    if(l<=tr[now].l&&tr[now].r<=r)
    {
        swap(tr[now].mess[0],tr[now].mess[1]);
        if(tr[now].lzd1!=-1)
            tr[now].lzd1^=1;
        else tr[now].lzd2^=1;
        return;
    }
    int mid=tr[now].l+tr[now].r>>1;
    lzd_down(now);
    if(l<=mid)
        reverse(now<<1,l,r);
    if(mid<r)
        reverse(now<<1|1,l,r);
    push_up(now);
}
int query_sum(int now,int l,int r)
{
    if(l<=tr[now].l&&tr[now].r<=r)
        return tr[now].mess[1].sum;
    int mid=tr[now].l+tr[now].r>>1,sum=0;
    lzd_down(now);
    if(l<=mid)
        sum+=query_sum(now<<1,l,r);
    if(mid<r)
        sum+=query_sum(now<<1|1,l,r);
    return sum;
}
node::message query_mess1(int now,int l,int r)
{
    if(l<=tr[now].l&&tr[now].r<=r)
        return tr[now].mess[1];
    int mid=tr[now].l+tr[now].r>>1;
    lzd_down(now);
    if(r<=mid)
        return query_mess1(now<<1,l,r);
    else if(l>mid)
        return query_mess1(now<<1|1,l,r);
    else return merge_mess(query_mess1(now<<1,l,r),query_mess1(now<<1|1,l,r),mid-max(l,tr[now].l)+1,min(r,tr[now].r)-mid);
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++)
        scanf("%d",a+i);
    build(1,0,n-1);
    while(m--)
    {
        int op,l,r;
        scanf("%d%d%d",&op,&l,&r);
        if(op<=1)
            change(1,l,r,op);
        else if(op==2)
            reverse(1,l,r);
        else if(op==3)
            printf("%d\n",query_sum(1,l,r));
        else printf("%d\n",query_mess1(1,l,r).m_len);
        //node::message mess=query_mess1(1,l,r);
        //printf("%d %d %d %d\n\n",mess.sum,mess.l_len,mess.r_len,mess.m_len);
    }
    return 0;
}

by what_else @ 2023-12-06 17:52:59

6,我看看


|