SOS

P2572 [SCOI2010] 序列操作

2007qqc_LiverpoolFC @ 2019-12-04 20:18:14

#include <bits/stdc++.h>
using namespace std;
struct node{
    int l,r,len,max[2],lmax[2],rmax[2],lazy,rev,sum;
}t[350010];
int a[100010],m,n;
void pushup(int k)
{
    t[k].sum=t[k*2].sum+t[2*k+1].sum;
    for(int i=0;i<=1;i++)
    {
        t[k].lmax[i]=t[k*2].lmax[i];
        if(i==1&&t[k*2].sum==t[k*2].r-t[k*2].l+1)t[k].lmax[i]+=t[k*2+1].lmax[i];
        else if(i==0&&t[k*2].sum==0)t[k].lmax[i]+=t[k*2+1].lmax[i];
        t[k].rmax[i]=t[k*2+1].rmax[i];
        if(i==1&&t[k*2+1].sum==t[k*2+1].r-t[k*2+1].l+1)t[k].rmax[i]+=t[k*2].rmax[i];
        else if(i==0&&t[k*2+1].sum==0)t[k].rmax[i]+=t[k*2].rmax[i];
        t[k].max[i]=max(t[k*2].rmax[i]+t[k*2+1].lmax[i],max(t[k*2].max[i],t[k*2+1].max[i]));
    }
}
void pushdown(int k)
{
    if(t[k].lazy>=0)
    {
        int s=t[k].lazy,now=k*2;
        t[k].rev=t[k].lazy=-1;
        t[now].rmax[s]=t[now].lmax[s]=t[now].max[s]=t[now].len;
        t[now].max[1-s]=t[now].lmax[1-s]=t[now].rmax[1-s]=0;
        t[now].lazy=s;
        t[now].sum=s*t[now].len;
        now=k*2+1;
        t[now].rmax[s]=t[now].lmax[s]=t[now].max[s]=t[now].len;
        t[now].max[1-s]=t[now].lmax[1-s]=t[now].rmax[1-s]=0;
        t[now].lazy=s;
        t[now].sum=s*t[now].len;
    }
    if(t[k].rev==0)
    {
        int now=k*2;
        t[k].rev=-1;
        swap(t[now].max[0],t[now].max[1]);
        swap(t[now].lmax[0],t[now].lmax[1]);
        swap(t[now].rmax[0],t[now].rmax[1]);
        t[now].rev=0;
        t[now].sum=t[now].len-t[now].sum;
        now=k*2+1;
        swap(t[now].max[0],t[now].max[1]);
        swap(t[now].lmax[0],t[now].lmax[1]);
        swap(t[now].rmax[0],t[now].rmax[1]);
        t[now].rev=0;
        t[now].sum=t[now].len-t[now].sum;
    }
}
void build(int now,int l,int r)
{
    t[now].l=l,t[now].r=r,t[now].len=r-l+1;
    t[now].rev=t[now].lazy=-1;
    if(l==r)
    {
        t[now].sum=a[l];
        t[now].max[a[l]]=t[now].lmax[a[l]]=t[now].rmax[a[l]]=1;
        t[now].max[1-a[l]]=t[now].lmax[1-a[l]]=t[now].rmax[1-a[l]]=0;
        return;
    }
    build(now*2,l,(l+r)/2);
    build(now*2+1,(l+r)/2+1,r);
    pushup(now);
}
void change(int l,int r,int now,int s)
{
    if(t[now].r<l||t[now].l>r)return;
    if(t[now].l>=l&&t[now].r<=r)
    {
        t[now].rmax[s]=t[now].lmax[s]=t[now].max[s]=t[now].len;
        t[now].max[1-s]=t[now].lmax[1-s]=t[now].rmax[1-s]=0;
        t[now].lazy=s;
        t[now].sum=s*t[now].len;
        return;
    }
    pushdown(now);
    change(l,r,now*2,s);
    change(l,r,now*2+1,s);
    pushup(now);
}
void rev(int l,int r,int now)
{
    if(t[now].r<l||t[now].l>r)return;
    if(t[now].l>=l&&t[now].r<=r)
    {
        swap(t[now].max[0],t[now].max[1]);
        swap(t[now].lmax[0],t[now].lmax[1]);
        swap(t[now].rmax[0],t[now].rmax[1]);
        t[now].rev=0;
        t[now].sum=t[now].len-t[now].sum;
        return;
    }
    pushdown(now);
    rev(l,r,now*2);
    rev(l,r,now*2+1);
    pushup(now);
}
int find_sum(int l,int r,int now)
{
    if(t[now].r<l||t[now].l>r)return 0;
    if(t[now].l>=l&&t[now].r<=r)return t[now].sum;
    pushdown(now);
    return find_sum(l,r,now*2)+find_sum(l,r,now*2+1);
}
node find_continue(int l,int r,int now)
{
    pushdown(now);
    if(t[now].l==l&&t[now].r==r)return t[now];
    int mid=(t[now].l+t[now].r)/2;
    if(mid<l)return find_continue(l,r,now*2+1);
    if(mid>=r)return find_continue(l,r,now*2);
    node find,L=find_continue(l,mid,now*2),R=find_continue(mid+1,r,now*2+1);
    find.sum=L.sum+R.sum;
    for(int i=0;i<=1;i++)
    {
        find.lmax[i]=L.lmax[i];
        if(i==1&&L.sum==L.len)find.lmax[i]+=R.lmax[i];
        if(i==0&&L.sum==0)find.lmax[i]+=R.lmax[i];
        find.rmax[i]=R.rmax[i];
        if(i==1&&R.sum==R.len)find.rmax[i]+=L.rmax[i];
        if(i==0&&R.sum==0)find.rmax[i]+=L.rmax[i];
        find.max[i]=max(L.rmax[i]+R.lmax[i],max(L.max[i],R.max[i]));
    }
    return find;
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++)scanf("%d",&a[i]);
    build(1,0,n-1);
    for(int i=1;i<=m;i++)
    {
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        if(x==0)change(y,z,1,0);
        else if(x==1)change(y,z,1,1);
        else if(x==2)rev(y,z,1);
        else if(x==3)printf("%d\n",find_sum(y,z,1));
        else printf("%d\n",find_continue(y,z,1).max[1]);
    }
    return 0;
}

by 1saunoya @ 2019-12-04 20:22:02

这题还是珂朵莉方便吧…


by 小粉兔 @ 2019-12-04 20:28:18

别问,问就是对拍


by installb @ 2019-12-04 20:40:54

首先你数组开小了


|