zoukankan      html  css  js  c++  java
  • poj 3667 Hotel

    Hotel
    Time Limit: 3000MS   Memory Limit: 65536K
    Total Submissions: 8874   Accepted: 3769

    Description

    The cows are journeying north to Thunder Bay in Canada to gain cultural enrichment and enjoy a vacation on the sunny shores of Lake Superior. Bessie, ever the competent travel agent, has named the Bullmoose Hotel on famed Cumberland Street as their vacation residence. This immense hotel has N (1 ≤ N ≤ 50,000) rooms all located on the same side of an extremely long hallway (all the better to see the lake, of course).

    The cows and other visitors arrive in groups of size Di (1 ≤ Di ≤ N) and approach the front desk to check in. Each group i requests a set of Di contiguous rooms from Canmuu, the moose staffing the counter. He assigns them some set of consecutive room numbers r..r+Di-1 if they are available or, if no contiguous set of rooms is available, politely suggests alternate lodging. Canmuu always chooses the value of r to be the smallest possible.

    Visitors also depart the hotel from groups of contiguous rooms. Checkout i has the parameters Xi and Di which specify the vacating of rooms Xi ..Xi +Di-1 (1 ≤ Xi  N-Di+1). Some (or all) of those rooms might be empty before the checkout.

    Your job is to assist Canmuu by processing M (1 ≤ M < 50,000) checkin/checkout requests. The hotel is initially unoccupied.

    Input

    * Line 1: Two space-separated integers: N and M
    * Lines 2..M+1: Line i+1 contains request expressed as one of two possible formats: (a) Two space separated integers representing a check-in request: 1 and Di (b) Three space-separated integers representing a check-out: 2, Xi, andDi

    Output

    * Lines 1.....: For each check-in request, output a single line with a single integer r, the first room in the contiguous sequence of rooms to be occupied. If the request cannot be satisfied, output 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
    

    Source

      1 /**
      2 题意:两个操作
      3 1  len  找是否存在连续的len长的空房子。
      4            如果有多个存在,选择最左边的。并输出最左边的位置的值
      5            
      6 2 L num 从L开始长为L+num-1的长度的房子清空。
      7 
      8 思路:
      9 
     10 操作2比较简单,延迟标记就行。
     11 操作1,需要统计lmaxn , rmaxn , maxn 来统计连续的0的个数; 
     12 这题和前面几题有所差异,我不需要lnum,rnum;
     13 其实需要不需要我们要看up(int n) 里是否需要。
     14 
     15 void up(int n)
     16 {
     17     f[n].lmaxn = (  f[n*2].lmaxn==f[n*2].len ) ? f[n*2].lmaxn+f[n*2+1].lmaxn : f[n*2].lmaxn;
     18     f[n].rmaxn = (  f[n*2+1].rmaxn == f[n*2+1].len ) ? f[n*2+1].rmaxn+f[n*2].rmaxn : f[n*2+1].rmaxn;
     19 
     20     f[n].maxn = max(f[n*2].maxn,f[n*2+1].maxn);
     21     f[n].maxn = max( f[n*2].rmaxn+f[n*2+1].lmaxn,f[n].maxn );
     22 }
     23 如果为lnum = 1  或 rnum = 1,那么其对应的值就是为0,所以相加也是没有关系的。
     24 可以不判断lnum, rnum;
     25 
     26 同时,讨论query() 。
     27 当左儿子节点的max>=len 时,递归到左儿子节点。
     28 如果此时不满足不是讨论  右儿子节点  而是讨论
     29 左儿子节点的右端点的最大值+右儿子节点的左端点的最大值是否满足>=len,即
     30 if(f[n*2].rmax+f[n*2+1].lmax>=len)
     31      return f[n*2].r-f[n*2].rmax+1;
     32 返回最左的端点位置。
     33 然后才是讨论右儿子节点的情况。
     34 **/
     35 #include<iostream>
     36 #include<stdio.h>
     37 #include<cstring>
     38 #include<cstdlib>
     39 using namespace std;
     40 
     41 struct node
     42 {
     43     int l,r,len;
     44     int lmaxn,rmaxn,maxn;
     45     bool setFlag;
     46     int setNum;
     47 }f[50002*4];
     48 
     49 void up(int n)
     50 {
     51     f[n].lmaxn = (  f[n*2].lmaxn==f[n*2].len ) ? f[n*2].lmaxn+f[n*2+1].lmaxn : f[n*2].lmaxn;
     52     f[n].rmaxn = (  f[n*2+1].rmaxn == f[n*2+1].len ) ? f[n*2+1].rmaxn+f[n*2].rmaxn : f[n*2+1].rmaxn;
     53 
     54     f[n].maxn = max(f[n*2].maxn,f[n*2+1].maxn);
     55     f[n].maxn = max( f[n*2].rmaxn+f[n*2+1].lmaxn,f[n].maxn );
     56 }
     57 void build(int l,int r,int n)
     58 {
     59     int mid=(l+r)/2;
     60     f[n].l = l;
     61     f[n].r = r;
     62     f[n].len = (r-l+1);
     63     f[n].setFlag = false;
     64     f[n].setNum = 0;
     65     f[n].lmaxn = f[n].rmaxn = f[n].maxn = 0;
     66     if(l == r)
     67     {
     68         f[n].lmaxn = f[n].rmaxn = f[n].maxn = 1;
     69         return ;
     70     }
     71     build(l,mid,n*2);
     72     build(mid+1,r,n*2+1);
     73     up(n);
     74 }
     75 
     76 void down(int n)
     77 {
     78     f[n*2].setFlag = true;
     79     f[n*2].setNum = f[n].setNum;
     80     f[n*2].lmaxn = f[n*2].rmaxn = f[n*2].maxn = f[n*2].len*f[n].setNum;
     81 
     82     f[n*2+1].setFlag = true;
     83     f[n*2+1].setNum = f[n].setNum;
     84     f[n*2+1].lmaxn = f[n*2+1].rmaxn = f[n*2+1].maxn = f[n*2+1].len*f[n].setNum;
     85 
     86     f[n].setFlag = false;
     87 }
     88 void update(int l,int r,int size1,int n)
     89 {
     90     int mid = (f[n].l + f[n].r)/2;
     91     if(f[n].l == l && f[n].r == r)
     92     {
     93         f[n].setFlag = true;
     94         f[n].setNum = size1;
     95         f[n].lmaxn = f[n].rmaxn = f[n].maxn = f[n].len*size1;
     96         return;
     97     }
     98     if(f[n].setFlag == true) down(n);
     99     if(mid>=r) update(l,r,size1,n*2);
    100     else if(mid<l) update(l,r,size1,n*2+1);
    101     else
    102     {
    103         update(l,mid,size1,n*2);
    104         update(mid+1,r,size1,n*2+1);
    105     }
    106     up(n);
    107 }
    108 
    109 int query(int len , int  n)
    110 {
    111     if(f[n].maxn<len) return 0;
    112     if(f[n].setFlag == true) down(n);
    113     if(f[n*2].maxn >= len) return query(len,n*2);
    114     else if(f[n*2].rmaxn + f[n*2+1].lmaxn>=len)
    115         return f[n*2].r - f[n*2].rmaxn +1;
    116     else return query(len,n*2+1);
    117 }
    118 int main()
    119 {
    120     int n,m;
    121     int size1,l,r,len;
    122     while(scanf("%d%d",&n,&m)>0)
    123     {
    124         build(1,n,1);
    125         while(m--)
    126         {
    127             scanf("%d",&size1);
    128             if(size1==1)
    129             {
    130                 scanf("%d",&len);
    131                 int ans = query(len,1);
    132                 printf("%d\n",ans);
    133                 if(ans>0) update(ans,ans+len-1,0,1);
    134             }
    135             else if(size1==2)
    136             {
    137                 scanf("%d%d",&l,&r);
    138                 r=l+r+-1;
    139                 update(l,r,1,1);
    140             }
    141         }
    142     }
    143     return 0;
    144 }
  • 相关阅读:
    题目一: 写一个Java程序,用于分析一个字符串中各个单词出现的频率,并将单词和它出现的频率输出显示。
    个人简介
    读《构建之法》有感
    四_测试网站管理系统
    一_测试入门
    三_白盒测试
    个人简介
    二_单元测试和代码覆盖率
    第五次博客作业 初读《构建之法》的心得体会
    第三次 博客作业
  • 原文地址:https://www.cnblogs.com/tom987690183/p/3063332.html
Copyright © 2011-2022 走看看