• bzoj千题计划177:bzoj1858: [Scoi2010]序列操作


    http://www.lydsy.com/JudgeOnline/problem.php?id=1858

    2018 自己写的第1题,一遍过

    ^_^

    元旦快乐

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    
    using namespace std;
    
    #define N 100001
    
    struct node
    {
        int siz;
        int L[2],R[2],con[2];
        int sum[2];
        bool rev;
        int cover;
    }tr[N<<2];
    
    struct node_
    {
        int L1,R1,con1;
        int siz;
    };
    
    node_ operator + (node_ l,node_ r)
    {
        node_ res;
        res.L1=l.L1;
        if(l.L1==l.siz) res.L1+=r.L1;
        res.R1=r.R1;
        if(r.R1==r.siz) res.R1+=l.R1;
        res.con1=max(l.con1,r.con1);
        res.con1=max(res.con1,l.R1+r.L1);
        return res;
    }
    
    int x;
    
    int ans;
    
    void read(int &x)
    {
        x=0; char c=getchar();
        while(!isdigit(c)) c=getchar();
        while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); }
    }
    
    void update(int k)
    {
        for(int i=0;i<=1;++i)
        {
            tr[k].L[i]=tr[k<<1].L[i];
            if(tr[k<<1].L[i]==tr[k<<1].siz) tr[k].L[i]+=tr[k<<1|1].L[i];
            tr[k].R[i]=tr[k<<1|1].R[i];
            if(tr[k<<1|1].R[i]==tr[k<<1|1].siz) tr[k].R[i]+=tr[k<<1].R[i];
            tr[k].con[i]=max(tr[k<<1].con[i],tr[k<<1|1].con[i]);
            tr[k].con[i]=max(tr[k].con[i],tr[k<<1].R[i]+tr[k<<1|1].L[i]);
            tr[k].sum[i]=tr[k<<1].sum[i]+tr[k<<1|1].sum[i];
        }
    }
    
    void build(int k,int l,int r)
    {
        tr[k].cover=-1;
        tr[k].siz=r-l+1;
        if(l==r)
        {
            read(x);
            tr[k].L[x]++;
            tr[k].R[x]++;
            tr[k].con[x]++;
            tr[k].sum[x]++;
            return;
        }
        int mid=l+r>>1;
        build(k<<1,l,mid);
        build(k<<1|1,mid+1,r);
        update(k);
    }
    
    void reverse(int k)
    {
        swap(tr[k].L[0],tr[k].L[1]);
        swap(tr[k].R[0],tr[k].R[1]);
        swap(tr[k].con[0],tr[k].con[1]);
        swap(tr[k].sum[0],tr[k].sum[1]);
        tr[k].rev^=1;
        if(tr[k].cover!=-1) tr[k].cover^=1;
    }
    
    void down_rev(int k)
    {
        reverse(k<<1);
        reverse(k<<1|1);
        tr[k].rev^=1;
    }
    
    void covering(int k,int w)
    {
        tr[k].L[w]=tr[k].R[w]=tr[k].con[w]=tr[k].sum[w]=tr[k].siz;
        tr[k].L[w^1]=tr[k].R[w^1]=tr[k].con[w^1]=tr[k].sum[w^1]=0;
        tr[k].cover=w;
        tr[k].rev=false;
    }
    
    void down_cov(int k)
    {
        covering(k<<1,tr[k].cover);
        covering(k<<1|1,tr[k].cover);
        tr[k].cover=-1;
    }
    
    void Cover(int k,int l,int r,int opl,int opr,int w)
    {
        if(l>=opl && r<=opr)
        {
            covering(k,w);
            return;
        }
        if(tr[k].rev) down_rev(k);
        if(tr[k].cover!=-1) down_cov(k);
        int mid=l+r>>1;
        if(opl<=mid) Cover(k<<1,l,mid,opl,opr,w);
        if(opr>mid) Cover(k<<1|1,mid+1,r,opl,opr,w);
        update(k);
    }
    
    void Reverse(int k,int l,int r,int opl,int opr)
    {
        if(l>=opl && r<=opr)
        {
            reverse(k);
            return;
        }
        if(tr[k].rev) down_rev(k);
        if(tr[k].cover!=-1) down_cov(k);
        int mid=l+r>>1;
        if(opl<=mid) Reverse(k<<1,l,mid,opl,opr);
        if(opr>mid) Reverse(k<<1|1,mid+1,r,opl,opr);
        update(k);
    }
    
    void query(int k,int l,int r,int opl,int opr)
    {
        if(l>=opl && r<=opr)
        {
            ans+=tr[k].sum[1];
            return;
        }
        if(tr[k].rev) down_rev(k);
        if(tr[k].cover!=-1) down_cov(k);
        int mid=l+r>>1;
        if(opl<=mid) query(k<<1,l,mid,opl,opr);
        if(opr>mid) query(k<<1|1,mid+1,r,opl,opr);
    }
    
    node_ Query(int k,int l,int r,int opl,int opr)
    {
        if(l>=opl && r<=opr)
        {
            node_ res;
            res.L1=tr[k].L[1];
            res.R1=tr[k].R[1];
            res.con1=tr[k].con[1];
            res.siz=tr[k].siz;
            return res;
        }
        if(tr[k].rev) down_rev(k);
        if(tr[k].cover!=-1) down_cov(k);
        int mid=l+r>>1;
        if(opr<=mid) return Query(k<<1,l,mid,opl,opr);
        if(opl>mid) return Query(k<<1|1,mid+1,r,opl,opr);
        return Query(k<<1,l,mid,opl,opr)+Query(k<<1|1,mid+1,r,opl,opr);
    }
    
    int main()
    {
        int n,m;
        read(n); read(m);
        build(1,1,n);
        int ty,l,r;
        while(m--)
        {
            read(ty); read(l); read(r);
            l++; r++;
            switch(ty)
            {
                case 0 : Cover(1,1,n,l,r,0); break;
                case 1 : Cover(1,1,n,l,r,1); break;
                case 2 : Reverse(1,1,n,l,r); break;
                case 3 : ans=0; query(1,1,n,l,r); cout<<ans<<'
    '; break;
                case 4 : printf("%d
    ",Query(1,1,n,l,r).con1); break;
            }
        }
    }
  • 相关阅读:
    Bootstrap(2)整体架构
    介绍 Microservice
    Websocket实例
    MYSQL-用户权限的验证过程(转)
    don't touch your phone in any unfamiliar way(转)
    你真的会玩SQL吗?Case的用法(转)
    android模拟器与PC的端口映射(转)
    Java Main如何被执行?(转)
    Linux crontab 命令格式与具体样例
    分享一个3D球面标签云
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/8168986.html
Copyright © 2020-2023  润新知