Description
The cows is journeying north to Thunder Bay in Canada to gain cultural enrichment and enjoy a vacation on the sunny shore S of Lake Superior. Bessie, ever the competent travel agent, had named the Bullmoose Hotel on famed Cumberland Street as their vacation reside nCE. This immense hotel have n (1≤ n ≤50,000) rooms all located on the same side of a extremely long hallwa Y (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 Chec K 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 the numbers R.. R+Di-1 if they is available or, if the 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 is 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.
The problem is basically to do two operations on a certain interval, which is to find the leftmost position that can accommodate D, and then update the interval to 0 or 1.
Typical interval coverage problem, maintaining maximum empty room and prefix maximum, suffix max three values.
The code is as follows:
#include <iostream>#include<cstdio>#include<cstring>#defineLson l,m,po*2#defineRson m+1,r,po*2+1#defineLC Po*2#defineRC Po*2+1using namespacestd;Const intmaxn=50005;intmsum[maxn*4],lsum[maxn*4],rsum[maxn*4];intcol[maxn*4];voidPushdown (intPointLen) { if(col[po]==1) {COL[LC]=col[rc]=1; MSUM[LC]=rsum[lc]=lsum[lc]=0; MSUM[RC]=rsum[rc]=lsum[rc]=0; COL[PO]=-1; } Else if(col[po]==0) {COL[LC]=col[rc]=0; MSUM[LC]=rsum[lc]=lsum[lc]=len-(len/2); MSUM[RC]=rsum[rc]=lsum[rc]=len/2; COL[PO]=-1; }}voidPushup (intPointLen) {Msum[po]=Max (MSUM[LC],MSUM[RC]); MSUM[PO]=max (msum[po],rsum[lc]+LSUM[RC]); LSUM[PO]=LSUM[LC]; if(lsum[lc]== (len-(len/2)) ) Lsum[po]+=LSUM[RC]; RSUM[PO]=RSUM[RC]; if(rsum[rc]==len/2) Rsum[po]+=RSUM[LC];}voidBuild_tree (intLintRintPO) {Col[po]=-1; MSUM[PO]=rsum[po]=lsum[po]=r-l+1; if(l==R)return; intM= (L+R)/2; Build_tree (Lson); Build_tree (Rson);}voidUpdateintUlinturintUtintLintRintPO) { if(ul<=l&&ur>=R) {Col[po]=ut; MSUM[PO]=lsum[po]=rsum[po]= (UT?)0: r-l+1); return; } pushdown (Po,r-l+1); intM= (L+R)/2; if(ul<=M) Update (Ul,ur,ut,lson); if(ur>M) Update (Ul,ur,ut,rson); Pushup (Po,r-l+1);}intQueryintLenintLintRintPO) { if(l==R)returnL; Pushdown (Po,r-l+1); intM= (L+R)/2; if(msum[lc]>=len)returnquery (Len,lson); Else if(rsum[lc]+lsum[rc]>=len)returnm-rsum[lc]+1; Else returnquery (Len,rson);}intMain () {intM,n; intA,b,c; while(~SCANF ("%d%d",&n,&M)) {Build_tree (1N1); for(intI=0; i<m;++i) {scanf ("%d%d",&a,&b); if(a==1) { if(msum[1]<b) printf ("%d\n",0); Else{C=query (b,1N1); Update (C,c+b-1,1,1N1); printf ("%d\n", c); } } Else{scanf ("%d",&B); Update (B,b+c-1,0,1N1); } } } return 0;}
View Code
Simple POJ 3667 Hotel, line segment tree + interval merge.