zoukankan      html  css  js  c++  java
  • 东北育才 Day4 T2 旅馆

    旅馆(hotel)

    【问题描述】

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

    【输入格式】

    从文件hotel.in中输入数据。

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

    【输出格式】

    输出到文件hotel.out中。

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

    【样例输入】

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

    1 6

    【样例输出】

    1
    4
    7
    0

    5

    【数据规模与约定】

    对于20%的数据, 1<=N<=100,1<=M<=200

    对于100%的数据,1 <= N <= 50000 ,1 <= M <= 50000,数据有梯度。

     

     

    一个很普通的线段树,单纯的不行(然而自己pushdown写错,还是图样);

    维护一下每个区间能住的最大前缀,能住的最大后缀,以及能住的最大连续长度;

    回溯的时候最大连续长度从左子连续最大,右子连续最大,左子后缀与右子前缀之和中取最大;

    几乎是裸线段树,复杂度就是一个O(n logn)的建树(预处理);

    以及O(m logn)的查询修改操作;

    以下代码

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<cmath>
     4 #include<algorithm>
     5 #define lson rt*2,l,(l+r)/2
     6 #define rson rt*2+1,(l+r)/2+1,r
     7 using namespace std;
     8 struct node{int ll,rl,le,mark;}tree[400010];
     9 void pushup(int rt,int l,int r)
    10 {
    11     int mid=(l+r)/2;
    12     tree[rt].ll=tree[rt*2].ll;
    13     tree[rt].rl=tree[rt*2+1].rl;
    14     if(tree[rt].ll==(mid-l+1)) tree[rt].ll+=tree[rt*2+1].ll;
    15     if(tree[rt].rl==(r-mid)) tree[rt].rl+=tree[rt*2].rl;
    16     tree[rt].le=max(tree[rt*2].rl+tree[rt*2+1].ll,max(tree[rt*2].le,tree[rt*2+1].le));
    17 }
    18 void Supdate(int rt,int l,int r,int x)
    19 {
    20     tree[rt].mark=x;
    21     if(x==0)
    22     {tree[rt].ll=0; tree[rt].rl=0; tree[rt].le=0;}
    23     else
    24     {tree[rt].ll=r-l+1; tree[rt].rl=r-l+1; tree[rt].le=r-l+1;}
    25 }
    26 void pushdown(int rt,int l,int r)
    27 {
    28     if(tree[rt].mark==-1) return;
    29     Supdate(lson,tree[rt].mark);
    30     Supdate(rson,tree[rt].mark);
    31     tree[rt].mark=-1;
    32 }
    33 void buildtree(int rt,int l,int r)
    34 {
    35     tree[rt].mark=-1;
    36     if(l==r)
    37     {
    38         tree[rt].ll=1;
    39         tree[rt].rl=1;
    40         tree[rt].le=1;
    41         return;
    42     }
    43     buildtree(lson);
    44     buildtree(rson);
    45     pushup(rt,l,r);
    46 }
    47 void update(int rt,int l,int r,int f,int t,int x)
    48 {
    49     int mid=(l+r)/2;
    50     if(l==f && r==t)
    51     {
    52         Supdate(rt,l,r,x);
    53         return;
    54     }
    55     pushdown(rt,l,r);
    56     if(t<=mid) update(lson,f,t,x);
    57     else if(f>mid) update(rson,f,t,x);
    58     else
    59     {update(lson,f,mid,x); update(rson,mid+1,t,x);}
    60     pushup(rt,l,r);
    61 }
    62 int query(int rt,int l,int r,int x)
    63 {
    64     pushdown(rt,l,r);
    65     if(tree[rt*2].le>=x) return query(lson,x);
    66     else if(tree[rt*2].rl+tree[rt*2+1].ll>=x) return (l+r)/2-tree[rt*2].rl+1;
    67     else return query(rson,x);
    68 }
    69 int main()
    70 {
    71 //  freopen("hotel.in","r",stdin);
    72 //  freopen("hotel.out","w",stdout);
    73     int n,m,i,lk,x,y;
    74     scanf("%d%d",&n,&m);
    75     buildtree(1,1,n);
    76     for(i=1;i<=m;++i)
    77     {
    78         scanf("%d",&lk);
    79         if(lk==1)
    80         {
    81             scanf("%d",&x);
    82             if(tree[1].le<x)
    83             {printf("0
    "); continue;}
    84             y=query(1,1,n,x);
    85             printf("%d
    ",y);
    86             update(1,1,n,y,y+x-1,0);
    87         }
    88         if(lk==2)
    89         {
    90             scanf("%d%d",&x,&y);
    91             y=x+y-1;
    92             update(1,1,n,x,y,1);
    93         }
    94     }
    95 }
    View Code
  • 相关阅读:
    WPF快速指导10:WPF中的事件及冒泡事件和隧道事件(预览事件)的区别
    改善C#程序的建议1:非用ICloneable不可的理由
    WPF快速指导5:验证
    改善C#程序的建议4:C#中标准Dispose模式的实现
    我所入选的微软技术社区电子报
    C#中new, override, virtual的具体用法
    C#中FCL迭代器模式的一点问题
    WPF快速指导3:数据绑定
    WPF快速指导2:模板
    C#高效编程话题集2(每期10话题)
  • 原文地址:https://www.cnblogs.com/hntk/p/7214367.html
Copyright © 2011-2022 走看看