【BZOJ】1858: [Scoi2010]序列操作-线段树

版权声明:转载请附带链接或评论 https://blog.csdn.net/corsica6/article/details/82356742

传送门:bzoj1858


题解

线段树,区间操作
区间赋值操作可以覆盖区间翻转操作。
操作时不断标记下传, p u s h d o w n 时执行覆盖操作。


代码

#include<bits/stdc++.h>
#define gc getchar()
#define si isdigit(c)
#define RI register
#define lc k<<1
#define rc k<<1|1
#define mid (((l)+(r))>>1)
using namespace std;
const int N=1e5+10;

int n,m,ori[N],op,a,b;

struct node{
    int st,zr,rv,cl,cr;
    int zmx,zlmx,zrmx;
    int omx,olmx,ormx;
    node(){st=-1;}
}t[N<<2];

char c;
inline void rd(int &x)
{
    c=gc;x=0;
    for(;!si;c=gc);
    for(;si;c=gc) x=x*10+(c^48);
}

inline void pushup(int k)
{
    t[k].zr=t[lc].zr+t[rc].zr;

    if(t[lc].zlmx==t[lc].cr-t[lc].cl+1) t[k].zlmx=t[lc].zlmx+t[rc].zlmx;
    else t[k].zlmx=t[lc].zlmx;
    if(t[rc].zrmx==t[rc].cr-t[rc].cl+1) t[k].zrmx=t[rc].zrmx+t[lc].zrmx;
    else t[k].zrmx=t[rc].zrmx;
    t[k].zmx=max(max(t[lc].zmx,t[rc].zmx),t[lc].zrmx+t[rc].zlmx);

    if(t[lc].olmx==t[lc].cr-t[lc].cl+1) t[k].olmx=t[lc].olmx+t[rc].olmx;
    else t[k].olmx=t[lc].olmx;
    if(t[rc].ormx==t[rc].cr-t[rc].cl+1) t[k].ormx=t[rc].ormx+t[lc].ormx;
    else t[k].ormx=t[rc].ormx;
    t[k].omx=max(max(t[lc].omx,t[rc].omx),t[lc].ormx+t[rc].olmx);
}

inline void pushdown(int k)
{
    if(t[k].cl==t[k].cr) return;
    if(t[k].st!=-1){
        int num= (!t[k].zr)?1:0;
        t[lc].rv=t[rc].rv=t[k].rv=0;
        t[lc].st=t[rc].st=num;t[k].st=-1;
        if(num){
            t[lc].zr=t[rc].zr=0;
            t[lc].zlmx=t[lc].zrmx=t[lc].zmx=0;
            t[rc].zlmx=t[rc].zrmx=t[rc].zmx=0;
            t[lc].olmx=t[lc].ormx=t[lc].omx=t[lc].cr-t[lc].cl+1;
            t[rc].olmx=t[rc].ormx=t[rc].omx=t[rc].cr-t[rc].cl+1;
        }else{
            t[lc].zr=t[lc].zlmx=t[lc].zrmx=t[lc].zmx=t[lc].cr-t[lc].cl+1;
            t[rc].zr=t[rc].zlmx=t[rc].zrmx=t[rc].zmx=t[rc].cr-t[rc].cl+1;
            t[lc].olmx=t[lc].ormx=t[lc].omx=0;
            t[rc].olmx=t[rc].ormx=t[rc].omx=0;
        }
    }else if(t[k].rv){
        t[lc].rv^=1;t[rc].rv^=1;
        t[lc].zr=t[lc].cr-t[lc].cl+1-t[lc].zr;t[rc].zr=t[rc].cr-t[rc].cl+1-t[rc].zr;
        t[k].rv=0;
        swap(t[lc].zlmx,t[lc].olmx);swap(t[lc].zrmx,t[lc].ormx);swap(t[lc].zmx,t[lc].omx);
        swap(t[rc].zlmx,t[rc].olmx);swap(t[rc].zrmx,t[rc].ormx);swap(t[rc].zmx,t[rc].omx);
    }
}

inline void build(int k,int l,int r)
{
    t[k].cl=l;t[k].cr=r;
    if(l==r) {
       if(ori[l]){t[k].omx=t[k].olmx=t[k].ormx=1;}
       else{t[k].zr=1;t[k].zmx=t[k].zlmx=t[k].zrmx=1;}
       return;
    }
    build(lc,l,mid);build(rc,mid+1,r);
    pushup(k);
}

inline void sett(int k,int l,int r,int L,int R,int num)
{
    pushdown(k);
    if(L<=l && r<=R){
       t[k].st=num;
       if(num){
          t[k].zr=t[k].zmx=t[k].zlmx=t[k].zrmx=0;
          t[k].omx=t[k].ormx=t[k].olmx=r-l+1;
       }else{
          t[k].zr=t[k].zmx=t[k].zlmx=t[k].zrmx=r-l+1;
          t[k].omx=t[k].olmx=t[k].ormx=0;
       }
       return;
    }
    if(L<=mid) sett(lc,l,mid,L,R,num);
    if(R>mid) sett(rc,mid+1,r,L,R,num);
    pushup(k);
}

inline void rever(int k,int l,int r,int L,int R)
{
    pushdown(k);
    if(L<=l && r<=R){
        t[k].rv^=1;t[k].zr=(r-l+1-t[k].zr);
        swap(t[k].zlmx,t[k].olmx);swap(t[k].zrmx,t[k].ormx);swap(t[k].zmx,t[k].omx);
        return;
    }
    if(L<=mid) rever(lc,l,mid,L,R);
    if(R>mid) rever(rc,mid+1,r,L,R);
    pushup(k);
}

inline int getsum(int k,int l,int r,int L,int R){
    pushdown(k);
    if(L<=l && r<=R) return r-l+1-t[k].zr;
    int re=0;
    if(L<=mid) re=getsum(lc,l,mid,L,R);
    if(R>mid) re+=getsum(rc,mid+1,r,L,R);
    return re;
}

inline node ask(int k,int l,int r,int L,int R)
{
    pushdown(k);
    if(L<=l && r<=R) return t[k];
    if(R<=mid) return ask(lc,l,mid,L,R);
    if(L>mid) return ask(rc,mid+1,r,L,R);
    node ql=ask(lc,l,mid,L,R),qr=ask(rc,mid+1,r,L,R),tp;
    tp.omx=max(ql.omx,qr.omx);
    tp.cl=ql.cl;tp.cr=qr.cr;
    if(ql.olmx==ql.cr-ql.cl+1) tp.olmx=ql.olmx+qr.olmx;
    else tp.olmx=ql.olmx;
    if(qr.ormx==qr.cr-qr.cl+1) tp.ormx=qr.ormx+ql.ormx;
    else tp.ormx=qr.ormx;
    tp.omx=max(tp.omx,ql.ormx+qr.olmx);
    return tp;
}

int main(){
    RI int i,j;
    rd(n);rd(m);
    for(i=1;i<=n;++i) rd(ori[i]);
    build(1,1,n);
    for(;m;--m){
        rd(op);rd(a);rd(b);a++;b++;
        if(op<2) sett(1,1,n,a,b,op);
        else if(op==2) rever(1,1,n,a,b);
        else if(op==3) printf("%d\n",getsum(1,1,n,a,b));
        else printf("%d\n",ask(1,1,n,a,b).omx);
    }
} 

猜你喜欢

转载自blog.csdn.net/corsica6/article/details/82356742
今日推荐