zoukankan      html  css  js  c++  java
  • bzoj1593 [Usaco2008 Feb]Hotel 旅馆(线段树)

    1593: [Usaco2008 Feb]Hotel 旅馆

    Time Limit: 10 Sec  Memory Limit: 64 MB
    Submit: 758  Solved: 419
    [Submit][Status][Discuss]

    Description

    奶牛们最近的旅游计划,是到苏必利尔湖畔,享受那里的湖光山色,以及明媚的阳光。作为整个旅游的策划者和负责人,贝茜选择在湖边的一家著名的旅馆住宿。这个巨大的旅馆一共有N (1 <= N <= 50,000)间客房,它们在同一层楼中顺次一字排开,在任何一个房间里,只需要拉开窗帘,就能见到波光粼粼的湖面。 贝茜一行,以及其他慕名而来的旅游者,都是一批批地来到旅馆的服务台,希望能订到D_i (1 <= D_i <= N)间连续的房间。服务台的接待工作也很简单:如果存在r满足编号为r..r+D_i-1的房间均空着,他就将这一批顾客安排到这些房间入住;如果没有满足条件的r,他会道歉说没有足够的空房间,请顾客们另找一家宾馆。如果有多个满足条件的r,服务员会选择其中最小的一个。 旅馆中的退房服务也是批量进行的。每一个退房请求由2个数字X_i、D_i 描述,表示编号为X_i..X_i+D_i-1 (1 <= X_i <= N-D_i+1)房间中的客人全部离开。退房前,请求退掉的房间中的一些,甚至是所有,可能本来就无人入住。 而你的工作,就是写一个程序,帮服务员为旅客安排房间。你的程序一共需要处理M (1 <= M < 50,000)个按输入次序到来的住店或退房的请求。第一个请求到来前,旅店中所有房间都是空闲的。

    Input

    * 第1行: 2个用空格隔开的整数:N、M

    * 第2..M+1行: 第i+1描述了第i个请求,如果它是一个订房请求,则用2个数字 1、D_i描述,数字间用空格隔开;如果它是一个退房请求,用3 个以空格隔开的数字2、X_i、D_i描述

    Output

    * 第1..??行: 对于每个订房请求,输出1个独占1行的数字:如果请求能被满足 ,输出满足条件的最小的r;如果请求无法被满足,输出0

    Sample Input

    10 6
    1 3
    1 3
    1 3
    1 3
    2 5 5
    1 6

    Sample Output

    1
    4
    7
    0
    5
     
    /*
    求最长空序列
    思路类似动态最大子段和 
    详见代码 
    */
    #include<iostream>
    #include<cstdio>
    
    #define N 50010
    
    using namespace std;
    int n,m;
    struct tree
    {
        int l,r,m,lm,rm,sum,flag;
    }tr[N<<2];
    
    void build(int now,int l,int r)
    {
        tr[now].l=l;tr[now].r=r;
        tr[now].lm=tr[now].rm=tr[now].m=tr[now].sum=r-l+1;
        if(l==r) return;
        int mid=(l+r)>>1;
        build(now<<1,l,mid);build(now<<1|1,mid+1,r);
    }
    
    void pushup(int now)
    {
        if(tr[now<<1].sum==tr[now<<1].m) tr[now].lm=tr[now<<1].sum+tr[now<<1|1].lm;
        else tr[now].lm=tr[now<<1].lm;
        if(tr[now<<1|1].sum==tr[now<<1|1].m)tr[now].rm=tr[now<<1|1].sum+tr[now<<1].rm;
        else tr[now].rm=tr[now<<1|1].rm;
        tr[now].m=max(tr[now<<1].m,tr[now<<1|1].m);
        tr[now].m=max(tr[now].m,tr[now<<1].rm+tr[now<<1|1].lm);
    }
    
    void pushdown(int now)
    {
        int tag=tr[now].flag;tr[now].flag=0;
        if(tag==1)
        {
            tr[now<<1].lm=tr[now<<1].rm=tr[now<<1].m=tr[now<<1].sum;
            tr[now<<1|1].lm=tr[now<<1|1].rm=tr[now<<1|1].m=tr[now<<1|1].sum;
            tr[now<<1].flag=tr[now<<1|1].flag=1;
        }
        else if(tag==2)
        {
            tr[now<<1].lm=tr[now<<1].rm=tr[now<<1].m=0;
            tr[now<<1|1].lm=tr[now<<1|1].rm=tr[now<<1|1].m=0;
            tr[now<<1].flag=tr[now<<1|1].flag=2;
        }
    }
    
    void change(int now,int l,int r,int f)
    {
        if(tr[now].l==l && tr[now].r==r)
        {
            if(f==1) tr[now].lm=tr[now].rm=tr[now].m=tr[now].sum;
            else tr[now].lm=tr[now].rm=tr[now].m=0;
            tr[now].flag=f;
            return;
        }
        if(tr[now].flag) pushdown(now);
        int mid=(tr[now].l+tr[now].r)>>1;
        if(r<=mid) change(now<<1,l,r,f);
        else if(l>mid) change(now<<1|1,l,r,f);
        else
        {
            change(now<<1,l,mid,f);
            change(now<<1|1,mid+1,r,f);
        }
        pushup(now);
    }
    
    int ask(int now,int x)
    {
        if(tr[now].flag) pushdown(now);
        int mid=(tr[now].l+tr[now].r)>>1;
        if(tr[now].l==tr[now].r) return tr[now].l;
        if(tr[now<<1].m>=x) return ask(now<<1,x);
        if(tr[now<<1].rm+tr[now<<1|1].lm>=x) return mid-tr[now<<1].rm+1;
        return ask(now<<1|1,x);
    }
    
    int main()
    {
        scanf("%d%d",&n,&m);
        build(1,1,n);
        for(int i=1;i<=m;i++)
        {
            int f,x,y;
            scanf("%d",&f);
            if(f==1)
            {
                scanf("%d",&x);
                if(tr[1].m<x) printf("0
    ");
                else
                {
                    int p=ask(1,x);
                    printf("%d
    ",p);
                    change(1,p,p+x-1,2);
                }
            }
            else 
            {
                scanf("%d%d",&x,&y);
                change(1,x,x+y-1,1);
            }
        }
        return 0;
    }
    折花枝,恨花枝,准拟花开人共卮,开时人去时。 怕相思,已相思,轮到相思没处辞,眉间露一丝。
  • 相关阅读:
    《Django By Example》第十二章(终章) 中文 翻译 (个人学习,渣翻)
    《Django By Example》第十一章 中文 翻译 (个人学习,渣翻)
    《Django By Example》第十章 中文 翻译 (个人学习,渣翻)
    《Django By Example》第九章 中文 翻译 (个人学习,渣翻)
    《Django By Example》第八章 中文 翻译 (个人学习,渣翻)
    《Django By Example》第五章 中文 翻译 (个人学习,渣翻)
    我的superui开源后台bootstrap开发框架
    LayoutInflater 总结
    Android屏幕分辨率概念(dp、dip、dpi、sp、px)
    android studio安装问题
  • 原文地址:https://www.cnblogs.com/L-Memory/p/7246835.html
Copyright © 2011-2022 走看看