zoukankan      html  css  js  c++  java
  • bzoj1858: [Scoi2010]序列操作

    lazy-tag线段树。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int maxn = 800000 + 10;
    
    struct Segtree {
        #define lc(x) ((x)<<1)
        #define rc(x) (((x)<<1)|1)
        
        int l[maxn],r[maxn];
        int l1[maxn],r1[maxn],con1[maxn],cnt1[maxn];
        int l0[maxn],r0[maxn],con0[maxn];
        int t1[maxn],t0[maxn],tr[maxn];
        
        void set1(int x) {
            l1[x]=r1[x]=con1[x]=cnt1[x]=r[x]-l[x]+1;
            l0[x]=r0[x]=con0[x]=0;
            t1[x]=1; t0[x]=tr[x]=0;    
        }
        
        void set0(int x) {
            l0[x]=r0[x]=con0[x]=r[x]-l[x]+1;
            l1[x]=r1[x]=con1[x]=cnt1[x]=0;
            t0[x]=1; t1[x]=tr[x]=0;
        }
        
        void inv(int x) {
            swap(l1[x],l0[x]);
            swap(r1[x],r0[x]);
            swap(con1[x],con0[x]);
            cnt1[x]=r[x]-l[x]+1-cnt1[x];    
            tr[x]^=1;
        }
        
        void push(int x) {
            if(t0[x]) {
                set0(lc(x));
                set0(rc(x));
                t0[x]=0;    
            }
            if(t1[x]) {
                set1(lc(x));
                set1(rc(x));
                t1[x]=0;
            }
            if(tr[x]) {
                inv(lc(x));
                inv(rc(x));
                tr[x]=0;
            }
        }
        
        void update(int x) {
            l1[x]=(l1[lc(x)]==r[lc(x)]-l[lc(x)]+1?l1[lc(x)]+l1[rc(x)]:l1[lc(x)]);
            r1[x]=(r1[rc(x)]==r[rc(x)]-l[rc(x)]+1?r1[rc(x)]+r1[lc(x)]:r1[rc(x)]);
            l0[x]=(l0[lc(x)]==r[lc(x)]-l[lc(x)]+1?l0[lc(x)]+l0[rc(x)]:l0[lc(x)]);
            r0[x]=(r0[rc(x)]==r[rc(x)]-l[rc(x)]+1?r0[rc(x)]+r0[lc(x)]:r0[rc(x)]);    
            con1[x]=max(max(con1[lc(x)],con1[rc(x)]),r1[lc(x)]+l1[rc(x)]);
            con0[x]=max(max(con0[lc(x)],con0[rc(x)]),r0[lc(x)]+l0[rc(x)]);
            cnt1[x]=cnt1[lc(x)]+cnt1[rc(x)];
        }
        
        void op0(int x,int L,int R) {
            push(x);
            if(R<l[x] || L>r[x]) return;
            if(L<=l[x] && r[x]<=R) {
                set0(x);
                return;
            }
            op0(lc(x),L,R);
            op0(rc(x),L,R);
            update(x);
        }
        
        void op1(int x,int L,int R) {
            push(x);
            if(R<l[x] || L>r[x]) return;
            if(L<=l[x] && r[x]<=R) {
                set1(x);
                return;
            }
            op1(lc(x),L,R);
            op1(rc(x),L,R);
            update(x);
        }
        
        void op2(int x,int L,int R) {
            push(x);
            if(R<l[x] || L>r[x]) return;
            if(L<=l[x] && r[x]<=R) {
                inv(x);
                return;
            }
            op2(lc(x),L,R);
            op2(rc(x),L,R);
            update(x);
        }
        
        int op3(int x,int L,int R) {
            push(x);
            if(R<l[x] || L>r[x]) return 0;
            if(L<=l[x] && r[x]<=R) return cnt1[x];
            return(op3(lc(x),L,R)+op3(rc(x),L,R));
        }
        
        int op4(int x,int L,int R) {
            push(x);
            if(R<l[x] || L>r[x]) return 0;
            if(L<=l[x] && r[x]<=R) return con1[x];
            return max(max(op4(lc(x),L,R),op4(rc(x),L,R)),min(r1[lc(x)],r[lc(x)]-L+1)+min(l1[rc(x)],R-l[rc(x)]+1));
        }
        
        void build(int x,int L,int R) {
            l[x]=L; r[x]=R;
            if(L==R) {
                int k;
                scanf("%d",&k);
                if(k) l1[x]=r1[x]=con1[x]=cnt1[x]=1;
                else l0[x]=r0[x]=con0[x]=1;    
                return;
            }
            int mid=(L+R)>>1;
            build(lc(x),L,mid);
            build(rc(x),mid+1,R);
            update(x);    
        }
    }seg;
    int n,m;
    
    int main() {
        scanf("%d%d",&n,&m);
        seg.build(1,0,n-1);
        for(int i=1,op,a,b;i<=m;i++) {
            scanf("%d%d%d",&op,&a,&b);
            if(op==0) seg.op0(1,a,b);
            else if(op==1) seg.op1(1,a,b);
            else if(op==2) seg.op2(1,a,b);
            else if(op==3) printf("%d
    ",seg.op3(1,a,b));
            else if(op==4) printf("%d
    ",seg.op4(1,a,b)); 
        }
        return 0;
    }
  • 相关阅读:
    Linux下安装mysql-5.7.30(笔记)
    配置jmeter、java环境变量
    离线安装grafana、influxdb
    Grafana接入influxdb数据,提示 “Failed to fetch”、“BAD GATAWAY”错误
    ALINX紫光同创国产FPGA开发板PGL22G发布
    ALINX紫光同创国产FPGA开发板PGL12G发布
    【紫光同创国产FPGA教程】【第二十八章】USB双向测速例程
    【紫光同创国产FPGA教程】【第二十七章】千兆以太网视频传输实验
    【紫光同创国产FPGA教程】【第二十六章】AD9280以太网传输
    【紫光同创国产FPGA教程】【第二十五章】AD7606以太网传输
  • 原文地址:https://www.cnblogs.com/invoid/p/5495964.html
Copyright © 2011-2022 走看看