zoukankan      html  css  js  c++  java
  • [USACO08FEB]酒店Hotel

    题目大意

    一段01序列,0代表没人住,1代表有人住,住房和退房都要求是修改一段连续区间.

    求能够安排住房的区间的左端点

    题解

    线段树

    要判断能否住 要维护区间0序列长最大值.和区间0序列最左边的长度和右边长度

    代码

    #include<cstdio>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    
    int sum[400010],lm[400010],rm[400010],m[400010],tag[400010],n,T;
    
    void pushup(int rt){
        if(m[rt<<1]==sum[rt<<1]){
            lm[rt]=m[rt<<1]+lm[rt<<1|1];
        }else{
            lm[rt]=lm[rt<<1];
        }
        if(m[rt<<1|1]==sum[rt<<1|1]){
            rm[rt]=m[rt<<1|1]+rm[rt<<1];
        }else{
            rm[rt]=rm[rt<<1|1];
        }
        m[rt]=max(max(m[rt<<1],m[rt<<1|1]),rm[rt<<1]+lm[rt<<1|1]);
        return;
    }
    
    void pushdown(int rt){
        if(tag[rt]==0)    return;
        if(tag[rt]==1){
            tag[rt<<1]=tag[rt<<1|1]=1;
            m[rt<<1]=lm[rt<<1]=rm[rt<<1]=0;
            m[rt<<1|1]=lm[rt<<1|1]=rm[rt<<1|1]=0;
        }
        if(tag[rt]==2){
            tag[rt<<1]=tag[rt<<1|1]=2;
            m[rt<<1]=lm[rt<<1]=rm[rt<<1]=sum[rt<<1];
            m[rt<<1|1]=lm[rt<<1|1]=rm[rt<<1|1]=sum[rt<<1|1];
        }
        tag[rt]=0;
    }
    
    void build(int rt,int l,int r){
        lm[rt]=rm[rt]=m[rt]=sum[rt]=r-l+1;
        tag[rt]=0;
        if(l==r) return;
        int mid=(l+r)>>1;
        build(rt<<1,l,mid);
        build(rt<<1|1,mid+1,r);
        return;
    }
    
    int query(int rt,int l,int r,int len){
        pushdown(rt);
        if(l==r)    return l;
        int mid=(l+r)>>1;
        if(m[rt<<1]>=len)    return query(rt<<1,l,mid,len);
        if(rm[rt<<1]+lm[rt<<1|1]>=len)    return mid-rm[rt<<1]+1;
        else    return query(rt<<1|1,mid+1,r,len);
    }
    
    void modify(int L,int R,int c,int rt,int l,int r){
        pushdown(rt);
        if((L<=l)&&(r<=R)){
            if(c==1) m[rt]=lm[rt]=rm[rt]=0;
            else m[rt]=lm[rt]=rm[rt]=sum[rt];
            tag[rt]=c;
            return;
        }
        int mid=(l+r)>>1;
        if(L<=mid)    modify(L,R,c,rt<<1,l,mid);
        if(R>mid)    modify(L,R,c,rt<<1|1,mid+1,r);
        pushup(rt);
    }
    
    int main(){
        scanf("%d%d",&n,&T);
        build(1,1,n);
        while(T--){
            int opt,a,b;
            scanf("%d",&opt);
            if(opt==1){
                scanf("%d",&a);
                if(m[1]<a){printf("0
    ");continue;}
                int p=query(1,1,n,a);
                printf("%d
    ",p);
                modify(p,p+a-1,1,1,1,n);
            }else{
                scanf("%d%d",&a,&b);
                modify(a,a+b-1,2,1,1,n);
            }
        }
        return 0;
    }
  • 相关阅读:
    ntp网络时间服务搭建
    Docker虚拟化容器的使用
    第06章 Linux文件权限体系讲解
    Linux命令总结--sed命令
    Linux命令总结--date命令
    第05章 正则表达式及相关命令
    子网划分
    第04章系统目录结构知识讲解
    第03章Linux基础优化
    2.5linux命令介绍
  • 原文地址:https://www.cnblogs.com/zzyh/p/7323751.html
Copyright © 2011-2022 走看看