球跳

P2572 [SCOI2010] 序列操作

liangcha_crush_ly @ 2024-12-20 19:33:55

#include<bits/stdc++.h>

using namespace std;
int n,m,a[101010],ch,l,r;
struct lyl{
    int l,r;
    int b,lb,rb,mb,c,lc,rc,mc;
    int len,fl1,fl2;
}tr[404040];
void pushup(lyl &dad,lyl ls,lyl rs){
    dad.b=ls.b+rs.b;
    dad.c=ls.c+rs.c;
    dad.lb=ls.c?ls.lb:ls.b+rs.lb;
    dad.rb=rs.c?rs.rb:rs.b+ls.rb;
    dad.mb=max(max(ls.mb,rs.mb),ls.rb+rs.lb);
    dad.lc=ls.b?ls.lc:ls.c+rs.lc;
    dad.rc=rs.b?rs.rc:rs.c+ls.rc;
    dad.mc=max(max(ls.mc,rs.mc),ls.rc+rs.lc);
    return;
}
void build(int p,int l,int r){
    int t=a[l];
    tr[p]={l,r,t,t,t,t,t^1,t^1,t^1,t^1,r-l+1,-1,0};
    if(l==r)return ;
    int mid=l+r>>1;
    build(p<<1,l,mid);
    build(p<<1|1,mid+1,r);
    pushup(tr[p],tr[p<<1],tr[p<<1|1]);
}
void pd(lyl &tr,int ch){
    if(ch==0){
        tr={l,r,0,0,0,0,tr.len,tr.len,tr.len,tr.len,tr.len,0,0};
    }
    if(ch==1){
        tr={l,r,tr.len,tr.len,tr.len,tr.len,tr.len,0,0,0,0,0,0};
    }
    if(ch==2){
        swap(tr.b,tr.c);swap(tr.lb,tr.lc);swap(tr.rb,tr.rc);swap(tr.mb,tr.mc);
        tr.fl2^=1;
    }
}
void pushdown(int p){
    lyl &t=tr[p];
    if(t.fl1)pd(tr[p<<1],t.fl1),pd(tr[p<<1|1],t.fl1);
    if(t.fl2)pd(tr[p<<1],2),pd(tr[p<<1|1],2);
    t.fl1=-1,t.fl2=0;
}
void change(int p,int l,int r,int ch){
    if(tr[p].l>r||tr[p].r<l)return;
    if(tr[p].r<=r&&tr[p].l>=l){
        pd(tr[p],ch);
        return;
    }
    change(p<<1,l,r,ch);
    change(p<<1|1,l,r,ch);
    pushup(tr[p],tr[p<<1],tr[p<<1|1]);
}
lyl quse(int p,int l,int r){
    if(tr[p].l>r||tr[p].r<l)return {};
    if(tr[p].r<=r&&tr[p].l>=l){
        return tr[p];
    }
    pushdown(p);
    lyl t;
    pushup(t,quse(p<<1,l,r),quse(p<<1|1,l,r));
    return t;
}
signed main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    build(1,1,n);
    for(int i=1;i<=m;i++){
        cin>>ch>>l>>r;
        if(ch<3)change(1,l,r,ch);
        else{
            lyl t;
            t=quse(1,l,r);
            if(ch==3)cout<<t.b+1<<endl;
            else cout<<t.mb+1<<endl;
        }
    }
    return 0;
}

|