• poj3667 区间合并,找最左边的空余块


    题很简单:给两个操作1:查找最左边的a个空余块并填满

              2:把从第a个开始的连续b个块置空

    线段树维护左连续,右连续,最大连续,lazy-tag即可,query函数值得学习

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define maxn 500005
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    int lmx[maxn<<2],rmx[maxn<<2],mx[maxn<<2],flag[maxn<<2];
    
    inline void set0(int l,int r,int rt){
        lmx[rt]=rmx[rt]=mx[rt]=r-l+1;
        flag[rt]=0;
    }
    inline void set1(int l,int r,int rt){
        lmx[rt]=rmx[rt]=mx[rt]=0;
        flag[rt]=1;
    }
    inline void pushup(int l,int r,int rt){
        lmx[rt]=lmx[rt<<1];rmx[rt]=rmx[rt<<1|1];
        mx[rt]=max(mx[rt<<1],mx[rt<<1|1]);
        int m=l+r>>1;
        if(lmx[rt<<1]==m-l+1) lmx[rt]+=lmx[rt<<1|1];
        if(rmx[rt<<1|1]==r-m) rmx[rt]+=rmx[rt<<1];
        if(rmx[rt<<1]&&lmx[rt<<1|1]) 
            mx[rt]=max(mx[rt],rmx[rt<<1]+lmx[rt<<1|1]);    
        
    }
    inline void pushdown(int l,int r,int rt){
        if(flag[rt]>=0){
            int m=l+r>>1; 
            flag[rt<<1]=flag[rt<<1|1]=flag[rt];
            if(flag[rt]==0){
                set0(lson);set0(rson);
            }
            else if(flag[rt]==1){
                set1(lson);set1(rson);
            }
            flag[rt]=-1;
        }
    }
    void build(int l,int r,int rt){
        if(l==r){
            lmx[rt]=rmx[rt]=mx[rt]=1;
            flag[rt]=-1;
            return;
        }
        int m=l+r>>1;
        build(lson);
        build(rson);
        pushup(l,r,rt);
    }
    void  update(int L,int R,int op,int l,int r,int rt){
        if(L<=l && R>=r){
            if(op==0) set0(l,r,rt);
            if(op==1) set1(l,r,rt);
            return;
        }
        pushdown(l,r,rt);
        int m=l+r>>1;
        if(L<=m) 
            update(L,R,op,lson);
        if(R>m)
            update(L,R,op,rson);
        pushup(l,r,rt);
    }
    //cnt要么在左儿子,要么在中间合并块,要么在右子树
    int query(int cnt,int l,int r,int rt){
        if(l==r)
            return l;
        pushdown(l,r,rt);
        int m=l+r>>1;
        if(cnt<=mx[rt<<1])
            return query(cnt,lson);
        else if(cnt<=rmx[rt<<1]+lmx[rt<<1|1])
            return m-rmx[rt<<1]+1;
        else 
            return query(cnt,rson);
    }
    int main(){
        int n,m;
        while(scanf("%d%d",&n,&m)==2){
            build(1,n,1);
            
            int a,b,op;
            while(m--){
                scanf("%d",&op);
                if(op==1){
                    scanf("%d",&a);
                    if(mx[1]<a){
                        puts("0");
                        continue;
                    }
                    int tmp=query(a,1,n,1);
                    printf("%d
    ",tmp);
                    update(tmp,tmp+a-1,1,1,n,1);
                }
                else if(op==2){
                    scanf("%d%d",&a,&b);
                    update(a,a+b-1,0,1,n,1);
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    助教观察记录5(10/21-11/3)
    助教观察记录4(10/07-10/20)
    助教观察记录3(9/23-10/06)
    助教观察记录1(9/5-9/15)
    2019年春季学期《C语言程序设计II》课程总结
    2020软件工程个人作业06——软件工程实践总结作业
    软件工程第二次作业
    2020软件工程作业3
    2020软件工程作业01
    神必高考数学题乱写
  • 原文地址:https://www.cnblogs.com/zsben991126/p/9977184.html
Copyright © 2020-2023  润新知