zoukankan      html  css  js  c++  java
  • 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)<<'
    '; 
            }
        }
    } 
  • 相关阅读:
    Oracle系列二 基本的SQL SELECT语句
    Oracle系列一 SQL语句基本概念和学习准备
    Android 动态更换桌面图标
    Linux_CentOS下搭建Nodejs 生产环境-以及nodejs进程管理器pm2的使用
    Linux_CentOS中Mongodb4.x 安装调试、远程管理、配置 mongodb 管理员密码
    Linux_CentOS 中systemctl 管理服务、防火墙 firewalld 以及 SELinux 配置
    Linux_CentOS 内存、cpu、进程、端口、硬盘管理
    Linux_CentOS中的MySQL 数据库的安装调试、远程管理
    LInux_CentosOS中yum安装jdk及配置环境变量
    Linux_CentOS软件安装调试 源代码包编译安装和 二进制包配置
  • 原文地址:https://www.cnblogs.com/zsben991126/p/9975879.html
Copyright © 2011-2022 走看看