poj 3667 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 }