• [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;
    }
  • 相关阅读:
    socket用法以及tomcat静态动态页面的加载
    SQL2000的三种“故障还原模型”
    杀毒软件拦截的,看不懂,留作纪念
    TOMCAT如何建立两个端口或服务
    非正常关机后造成数据库 置疑 状态的解决办法
    各数据表的空间使用量
    SQL Server 2008维护计划 出错 无法实现自动备份
    SQL2008安装自动退出
    oracle自动备份
    吐槽一下金山卫士
  • 原文地址:https://www.cnblogs.com/zzyh/p/7323751.html
Copyright © 2020-2023  润新知