hdu3397区间覆盖,区间翻转,区间合并,区间求和

调了很久的代码。。注意区间翻转和覆盖的操作互相的影响

/*
区间替换操作怎么搞?
应该是加个tag标记
如果整个区间都是0|1,那么把若有tag的话直接set1|0即可,也不用设置tag标记 
反之要设置tag标记,设置了tag标记的区间mx0和mx1要对换
lazy标记可以覆盖tag 
mx0,mx1表示区间0,1最大连续,lmx0,lmx1表示区间左连续,rmx0,rmx1表示区间右连续 
*/
#include<bits/stdc++.h>
using namespace std;
#define maxn 200005
int t,n,m,a[maxn];

#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
int mx0[maxn<<2],mx1[maxn<<2],lmx0[maxn<<2],rmx0[maxn<<2],lmx1[maxn<<2],rmx1[maxn<<2];
int sum[maxn<<2],lazy[maxn<<2],tag[maxn<<2];
void set0(int l,int r,int rt){tag[rt]=0;lazy[rt]=0;mx0[rt]=lmx0[rt]=rmx0[rt]=r-l+1;sum[rt]=mx1[rt]=lmx1[rt]=rmx1[rt]=0;}
void set1(int l,int r,int rt){tag[rt]=0;lazy[rt]=1;mx0[rt]=lmx0[rt]=rmx0[rt]=0;sum[rt]=mx1[rt]=lmx1[rt]=rmx1[rt]=r-l+1;}
void rev(int l,int r,int rt){
    if(lazy[rt]==0)set1(l,r,rt);
    else if(lazy[rt]==1)set0(l,r,rt);
    else {
        tag[rt]^=1;
        sum[rt]=r-l+1-sum[rt];
        swap(mx0[rt],mx1[rt]);
        swap(lmx0[rt],lmx1[rt]);
        swap(rmx0[rt],rmx1[rt]);
    }
}
void pushup(int l,int r,int rt){
    int m=l+r>>1;
    lmx0[rt]=lmx0[rt<<1],rmx0[rt]=rmx0[rt<<1|1];
    mx0[rt]=max(mx0[rt<<1],mx0[rt<<1|1]);
    if(rmx0[rt<<1]==m-l+1)lmx0[rt]=lmx0[rt<<1|1]+m-l+1;
    if(lmx0[rt<<1|1]==r-m)rmx0[rt]=rmx0[rt<<1]+r-m;
    mx0[rt]=max(mx0[rt],max(lmx0[rt],rmx0[rt]));
    mx0[rt]=max(mx0[rt],rmx0[rt<<1]+lmx0[rt<<1|1]);
    
    lmx1[rt]=lmx1[rt<<1],rmx1[rt]=rmx1[rt<<1|1];
    mx1[rt]=max(mx1[rt<<1],mx1[rt<<1|1]);
    if(rmx1[rt<<1]==m-l+1)lmx1[rt]=lmx1[rt<<1|1]+m-l+1;
    if(lmx1[rt<<1|1]==r-m)rmx1[rt]=rmx1[rt<<1]+r-m;
    mx1[rt]=max(mx1[rt],max(lmx1[rt],rmx1[rt]));
    mx1[rt]=max(mx1[rt],rmx1[rt<<1]+lmx1[rt<<1|1]);
    
    sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void pushdown(int l,int r,int rt){
    int m=l+r>>1;
    if(lazy[rt]==0){set0(lson);set0(rson);lazy[rt]=-1;return;}
    else if(lazy[rt]==1){set1(lson),set1(rson);lazy[rt]=-1;return;}
    else if(tag[rt]){rev(lson);rev(rson);tag[rt]=0;return;} 
}
void build(int l,int r,int rt){
    lazy[rt]=-1;
    tag[rt]=sum[rt]=0;
    if(l==r){
        if(a[l]==0){mx0[rt]=lmx0[rt]=rmx0[rt]=1;mx1[rt]=lmx1[rt]=rmx1[rt]=0;}
        else{mx0[rt]=lmx0[rt]=rmx0[rt]=0;mx1[rt]=lmx1[rt]=rmx1[rt]=sum[rt]=1;}
        return;
    }
    int m=l+r>>1;
    build(lson);build(rson);
    pushup(l,r,rt); 
}
void update0(int L,int R,int l,int r,int rt){
    if(L<=l && R>=r){set0(l,r,rt);return;}
    int m=l+r>>1;
    pushdown(l,r,rt);
    if(L<=m)update0(L,R,lson);
    if(R>m)update0(L,R,rson);
    pushup(l,r,rt);
}
void update1(int L,int R,int l,int r,int rt){
    if(L<=l && R>=r){set1(l,r,rt);return;}
    int m=l+r>>1;
    pushdown(l,r,rt);
    if(L<=m)update1(L,R,lson);
    if(R>m)update1(L,R,rson);
    pushup(l,r,rt);
}
void update2(int L,int R,int l,int r,int rt){
    if(L<=l && R>=r){rev(l,r,rt);return;}
    int m=l+r>>1;
    pushdown(l,r,rt);
    if(L<=m)update2(L,R,lson);
    if(R>m)update2(L,R,rson);
    pushup(l,r,rt);
}
int query1(int L,int R,int l,int r,int rt){
    if(L<=l &&R>=r){return sum[rt];}
    int m=l+r>>1,res=0;
    pushdown(l,r,rt);
    if(L<=m)res+=query1(L,R,lson);
    if(R>m)res+=query1(L,R,rson);
    pushup(l,r,rt); 
    return res;
}
int query2(int L,int R,int l,int r,int rt){
    if(L<=l && R>=r){return mx1[rt];}
    int m=l+r>>1;
    pushdown(l,r,rt);
    if(R<=m)return query2(L,R,lson);
    else if(L>m)return query2(L,R,rson);
    else {
        int t1=query2(L,R,lson),t2=query2(L,R,rson);
        int t3=max(t1,t2);
        return max(t3,min(rmx1[rt<<1],m-L+1)+min(lmx1[rt<<1|1],R-m));
    }
    pushup(l,r,rt);
}

int main(){
    cin>>t;
    while(t--){
        cin>>n>>m;
        for(int i=0;i<n;i++)cin>>a[i];
        build(0,n-1,1);
        while(m--){
            int opt,l,r;
            cin>>opt>>l>>r;
            //l++,r++;
            if(opt==0)update0(l,r,0,n-1,1);
            if(opt==1)update1(l,r,0,n-1,1);
            if(opt==2)update2(l,r,0,n-1,1);
            if(opt==3)cout<<query1(l,r,0,n-1,1)<<'
';
            if(opt==4)cout<<query2(l,r,0,n-1,1)<<'
'; 
        }
    }
} 
原文地址:https://www.cnblogs.com/zsben991126/p/9975879.html