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 }

 

 

 

你可能感兴趣的:(poj)