40pts 求调

P2572 [SCOI2010] 序列操作

Shizaki_Crazy_Three @ 2024-09-22 20:31:37

#include<bits/stdc++.h>
using namespace std;
struct tree{
    int l;int r;
    int over;
    int value;
    int ll,rl;
    int sum;
    int len;
    int lv;int rv;
    bool used;
    int l0,r0;
    int value0;
    int sum0;
    int used1;
}t[100005*4];
int n,m;
int a[100005];
inline void pushup(int p){
    t[p].value=t[p<<1].value+t[p<<1|1].value;
    t[p].lv=t[p<<1].lv;
    t[p].rv=t[p<<1|1].rv;
    if(t[p<<1].rv&&t[p<<1|1].lv){
        t[p].sum=max(t[p<<1].sum,max(t[p<<1|1].sum,t[p<<1].rl+t[p<<1|1].ll));
        if(t[p<<1].ll==t[p<<1].len) t[p].ll=t[p<<1].ll+t[p<<1|1].ll;
        else t[p].ll=t[p<<1].ll;
        if(t[p<<1|1].rl==t[p<<1|1].len) t[p].rl=t[p<<1|1].rl+t[p<<1].rl;
        else t[p].rl=t[p<<1|1].rl;
    }else {
        t[p].sum=max(t[p<<1].sum,t[p<<1|1].sum);
        t[p].ll=t[p<<1].ll;
        t[p].rl=t[p<<1|1].rl;
    }
    t[p].value0=t[p<<1].value0+t[p<<1|1].value0;
    if(!t[p<<1].rv&&!t[p<<1|1].lv){
        t[p].sum0=max(t[p<<1].sum0,max(t[p<<1|1].sum0,t[p<<1].r0+t[p<<1|1].l0));
        if(t[p<<1].l0==t[p<<1].len) t[p].l0=t[p<<1].l0+t[p<<1|1].l0;
        else t[p].l0=t[p<<1].l0;
        if(t[p<<1|1].r0==t[p<<1|1].len) t[p].r0=t[p<<1|1].r0+t[p<<1].r0;
        else t[p].r0=t[p<<1|1].r0;
    }else {
        t[p].sum0=max(t[p<<1].sum0,t[p<<1|1].sum0);
        t[p].l0=t[p<<1].l0;
        t[p].r0=t[p<<1|1].r0;
    }

}
inline void build(int p,int l,int r){
    t[p].l=l;
    t[p].r=r;
    t[p].len=r-l+1;
    if(l==r){
        t[p].l0=t[p].r0=t[p].sum0=t[p].value0=!a[l];
        t[p].lv=t[p].rv=t[p].value=t[p].sum=t[p].ll=t[p].rl=a[l];
        return;
    }
    int mid=l+r>>1;
    build(p<<1,l,mid);
    build(p<<1|1,mid+1,r);
    pushup(p);
}
inline void spread(int p){
    if(t[p].used){
        t[p<<1].lv=t[p<<1].rv=t[p<<1|1].lv=t[p].rv=t[p].over;
        t[p<<1].sum=t[p<<1].value=t[p<<1].ll=t[p<<1].rl=(t[p<<1].r-t[p<<1].l+1)*t[p].over;
        t[p<<1|1].sum=t[p<<1|1].value=t[p<<1|1].ll=t[p<<1|1].rl=(t[p<<1|1].r-t[p<<1|1].l+1)*t[p].over;
        t[p<<1].sum0=t[p<<1].value0=t[p<<1].l0=t[p<<1].r0=(t[p<<1].r-t[p<<1].l+1)*!t[p].over;
        t[p<<1|1].sum0=t[p<<1|1].value0=t[p<<1|1].l0=t[p<<1|1].r0=(t[p<<1|1].r-t[p<<1|1].l+1)*!t[p].over;
        t[p<<1].used=t[p<<1|1].used=1;
        t[p<<1].over=t[p<<1|1].over=t[p].over;
    }else if(t[p].used1){
        swap(t[p<<1].sum,t[p<<1].sum0);
        swap(t[p<<1].ll,t[p<<1].l0);
        swap(t[p<<1].rl,t[p<<1].r0);
        swap(t[p<<1].value,t[p<<1].value0);
        swap(t[p<<1|1].sum,t[p<<1|1].sum0);
        swap(t[p<<1|1].ll,t[p<<1|1].l0);
        swap(t[p<<1|1].rl,t[p<<1|1].r0);
        swap(t[p<<1|1].value,t[p<<1|1].value0);
        t[p<<1].used1^=1;
        t[p<<1].lv=!t[p<<1].lv;
        t[p<<1].rv=!t[p<<1].rv;
        t[p<<1|1].used1^=1;
        t[p<<1|1].lv=!t[p<<1|1].lv;
        t[p<<1|1].rv=!t[p<<1|1].rv;
        if(t[p<<1].used==1) t[p<<1].over^=1;
        if(t[p<<1|1].used==1) t[p<<1|1].over^=1;
    }
    t[p].used=t[p].over=t[p].used1=0;
}
inline void change(int p,int l,int r,int opt){
        spread(p);
    if(l<=t[p].l&&r>=t[p].r){
        t[p].lv=t[p].rv=opt;
        t[p].sum=t[p].value=t[p].ll=t[p].rl=(t[p].r-t[p].l+1)*opt;
        t[p].sum0=t[p].value0=t[p].l0=t[p].r0=(t[p].r-t[p].l+1)*!opt;
        t[p].over=opt;
        t[p].used=1;
        return;
    }
    spread(p);
    int mid=t[p].l+t[p].r>>1;
    if(l<=mid) change(p<<1,l,r,opt);
    if(r>mid) change(p<<1|1,l,r,opt);
    pushup(p);
}
inline void change1(int p,int l,int r){
    spread(p);
    if(l<=t[p].l&&r>=t[p].r){
        swap(t[p].sum,t[p].sum0);
        swap(t[p].ll,t[p].l0);
        swap(t[p].rl,t[p].r0);
        swap(t[p].value,t[p].value0);
        if(t[p].used==1) t[p].over^=1;
        t[p].used1^=1;
        t[p].lv=!t[p].lv;
        t[p].rv=!t[p].rv;
        return;
    }
    spread(p);
    int mid=t[p].l+t[p].r>>1;
    if(l<=mid) change1(p<<1,l,r);
    if(r>mid) change1(p<<1|1,l,r);
    spread(p);
    pushup(p);
} 
inline int ask(int p,int l,int r){
        spread(p);
    if(l<=t[p].l&&r>=t[p].r){
        return t[p].value;
    }
    spread(p);
    int ans=0;
    int mid=t[p].l+t[p].r>>1;
    if(l<=mid) ans+=ask(p<<1,l,r);
    if(r>mid) ans+=ask(p<<1|1,l,r);
    return ans; 
}
struct op{
    int sum,ll,rl;
    int lv,rv;
    int len;
}kong;
inline op ask1(int p,int l,int r){
    spread(p);
    if(l<=t[p].l&&r>=t[p].r){
    //cout<<111111<<' '<<t[p].l<<' '<<t[p].r<<' '<<t[p].sum<<' '<<t[p].lv<<' '<<t[p].rv<<endl;
        return  (op){t[p].sum,t[p].ll,t[p].rl,t[p].lv,t[p].rv,t[p].len};
    }
    spread(p);
    op temp=kong,temp1=kong,pp=kong;
    int mid=t[p].l+t[p].r>>1;
    if(l<=mid){
        temp=ask1(p<<1,l,r);
    }
        spread(p);
    if(r>mid){
        temp1=ask1(p<<1|1,l,r);
    }
//  cout<<2<<' '<<temp.sum<<' '<<temp1.sum<<endl;
    pp.lv=temp.lv;
    pp.rv=temp1.rv;
    if(temp.rv&&temp1.lv){
        pp.sum=max(temp.sum,max(temp1.sum,temp.rl+temp1.ll));
        if(temp.ll==temp.len) pp.ll=temp.ll+temp1.ll;
        else pp.ll=temp.ll;
        if(temp1.rl==temp1.len) pp.rl=temp1.rl+temp.rl;
        else pp.rl=temp1.rl;
    }else {
        pp.sum=max(temp.sum,temp1.sum);
        pp.ll=temp.ll;
        pp.rl=temp1.rl;
    }
/*  if(!temp.rv&&!temp1.lv){
        pp.sum=max(temp.sum0,max(temp1.sum0,temp.r0+temp1.l0));
        if(temp.l0==temp.len) pp.ll=temp.l0+temp1.l0;
        else pp.l0=temp.l0;
        if(temp1.r0==temp1.len) pp.r0=temp1.r0+temp.r0;
        else pp.r0=temp1.r0;
    }else {
        pp.sum0=max(temp.sum0,temp1.sum0);
        pp.l0=temp.l0;
        pp.r0=temp1.r0;
    }
    pp.len=temp.len+temp1.len;*/
//  cout<<pp.l<<' '<<t[p].r<<' '<<p<<' '<<pp.sum<<' '<<pp.ll<<' '<<pp.rl<<endl; 
    return pp;
}
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;
    for(int i=1;i<=m;i++){
        scanf("%d%d%d",&opt,&l,&r);
        l++;
        r++;
        if(opt==0){
            change(1,l,r,opt);
        }else if(opt==1){
            change(1,l,r,opt);
        }else if(opt==2){
            change1(1,l,r);
        }else if(opt==3){
            printf("%d\n",ask(1,l,r));
        }else{
            printf("%d\n",ask1(1,l,r).sum);
        }
    }
    return 0;
}

by Shizaki_Crazy_Three @ 2024-09-22 20:32:16

hack数据也行


|