• bzoj千题计划280:bzoj4592: [Shoi2015]脑洞治疗仪


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

    注意操作1 先挖再补,就是补的范围可以包含挖的范围

    SHOI2015 的题 略水啊(逃)

    #include<cstdio>
    #include<iostream>
    
    #define N 200001
    
    using namespace std;
    
    #define max(x,y) ((x)>(y) ? (x) : (y))
    #define min(x,y) ((x)<(y) ? (x) : (y))
    
    struct node
    {
        int L0,R0,mx0;
        int siz;
        
        node operator + (node p) const
        {
            node A;
            A.L0=L0;
            if(L0==siz) A.L0+=p.L0;
            A.R0=p.R0;
            if(p.R0==p.siz) A.R0+=R0;
            A.mx0=max(mx0,p.mx0);
            A.mx0=max(A.mx0,R0+p.L0);
            A.siz=siz+p.siz;
            return A;
        }
        
    }tr[N<<2];
    
    int sum1[N<<2];
    int tag[N<<2];
    
    int tot;
    
    int n;
    
    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 build(int k,int l,int r)
    {
        tag[k]=-1; 
        tr[k].L0=tr[k].R0=tr[k].mx0=0;
        tr[k].siz=sum1[k]=r-l+1;
        if(l==r) return;
        int mid=l+r>>1;
        build(k<<1,l,mid);
        build(k<<1|1,mid+1,r);
    }
    
    void tagging(int k,int w)
    {
        if(w) sum1[k]=tr[k].siz,tr[k].L0=tr[k].R0=tr[k].mx0=0;
        else sum1[k]=0,tr[k].L0=tr[k].R0=tr[k].mx0=tr[k].siz;
        tag[k]=w;
    }
    
    void down(int k)
    {
        tagging(k<<1,tag[k]);
        tagging(k<<1|1,tag[k]);
        tag[k]=-1;
    }
    
    void change(int k,int l,int r,int opl,int opr,int w)
    {
        if(l>=opl && r<=opr)
        {
            tagging(k,w);
            return;
        }
        if(tag[k]!=-1) down(k);
        int mid=l+r>>1;
        if(opl<=mid) change(k<<1,l,mid,opl,opr,w);
        if(opr>mid) change(k<<1|1,mid+1,r,opl,opr,w);
        sum1[k]=sum1[k<<1]+sum1[k<<1|1];
        tr[k]=tr[k<<1]+tr[k<<1|1];
    }
    
    void query(int k,int l,int r,int opl,int opr,int w)
    {
        if(l>=opl && r<=opr)
        {
            if(w) tot+=sum1[k];
            else tot+=tr[k].siz-sum1[k];
            return;
        }
        if(tag[k]!=-1) down(k);
        int mid=l+r>>1;
        if(opl<=mid) query(k<<1,l,mid,opl,opr,w);
        if(opr>mid) query(k<<1|1,mid+1,r,opl,opr,w);
    }
    
    int find(int L,int cnt)
    {
        int R=L,mid;
        int l=L,r=n;
        while(l<=r)
        {
            mid=l+r>>1;
            tot=0;
            query(1,1,n,L,mid,0);
            if(tot<=cnt) l=mid+1,R=mid;
            else r=mid-1;
        }
        return R;
    }
    
    node Query(int k,int l,int r,int opl,int opr)
    {
        if(l==opl && r==opr) return tr[k];
        if(tag[k]!=-1) down(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,mid)+Query(k<<1|1,mid+1,r,mid+1,opr);
    }
    
    int main()
    {
        int m;
        read(n); read(m);
        build(1,1,n);
        int ty,l,r,ll,rr;
        int pos;
        while(m--)
        {
            read(ty); read(l); read(r);
            if(!ty) change(1,1,n,l,r,0);
            else if(ty==1)
            {
                tot=0;
                query(1,1,n,l,r,1);
                change(1,1,n,l,r,0);
                read(ll); read(rr);
                if(!tot) continue;
                pos=find(ll,tot); //从l起,tot个1能补到哪儿 
                change(1,1,n,ll,min(pos,rr),1);
            }
            else printf("%d
    ",Query(1,1,n,l,r).mx0);
        }
    }
  • 相关阅读:
    for each/in
    对象与结构体的区别
    php与构造函数和析构函数
    回顾PHP之类与对象
    回顾PHP之数组篇
    正则个人总结
    echo 与print_r??
    六月学习与感想
    晚到的五月博客
    java复习
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/8566174.html
Copyright © 2020-2023  润新知