题目:Parking Lot
传送门:http://codeforces.com/problemset/problem/46/D
分析:
做法一:
1)这题和Hotel那题一样,也可以看做是求区间空位的问题,不过相对于Hotel那题细节会更多一些。
2)头和尾是不用考虑前和后是否有车的,但可以在$-B$和$L+F$这两个位置假装停了一辆车,这样就不用考虑第一辆插入的车和插入在最后的车啦,减少思考量。
代码:
#include <cstdio> #include <algorithm> using namespace std; const int maxN=100500; int a[110],b[110]; struct Segment{ int setL,setR,setN; int l0[maxN<<2],r0[maxN<<2],m0[maxN<<2],tag[maxN<<2]; void Down(int v,int l,int r){ if(tag[v]==-1)return; int mid=(l+r)>>1; l0[v<<1]=r0[v<<1]=m0[v<<1]=(!tag[v])*(mid-l+1); l0[v<<1^1]=r0[v<<1^1]=m0[v<<1^1]=(!tag[v])*(r-mid); tag[v<<1]=tag[v<<1^1]=tag[v];tag[v]=-1; } void Up(int v,int l,int r){ int mid=(l+r)>>1; if(l0[v<<1]==(mid-l+1))l0[v]=l0[v<<1]+l0[v<<1^1];else l0[v]=l0[v<<1]; if(r0[v<<1^1]==(r-mid))r0[v]=r0[v<<1]+r0[v<<1^1];else r0[v]=r0[v<<1^1]; m0[v]=max(max(m0[v<<1],m0[v<<1^1]),r0[v<<1]+l0[v<<1^1]); } int que(int v,int l,int r){ if(l==r)return l; Down(v,l,r); int mid=(l+r)>>1; if(m0[v<<1]>=setN)return que(v<<1,l,mid); if(r0[v<<1]+l0[v<<1^1]>=setN) return mid-r0[v<<1]+1; return que(v<<1^1,mid+1,r); } void set(int v,int l,int r){ if(setL<=l && r<=setR){ l0[v]=r0[v]=m0[v]=(!setN)*(r-l+1); tag[v]=setN;return; } Down(v,l,r); int mid=(l+r)>>1; if(setL<=mid)set(v<<1,l,mid); if(mid< setR)set(v<<1^1,mid+1,r); Up(v,l,r); } }T; int main(){ int L,B,F,n; scanf("%d%d%d%d",&L,&B,&F,&n); T.l0[1]=T.r0[1]=T.m0[1]=B+L+F; for(int op,x,d,td,i=1;i<=n;++i){ scanf("%d",&op); if(op==1){ scanf("%d",&td);d=B+td+F; if(T.m0[1]<d)puts("-1"); else{ T.setN=d;x=T.que(1,-B,L+F-1); a[i]=T.setL=x+B;b[i]=T.setR=a[i]+td-1;T.setN=1; T.set(1,-B,L+F-1); printf("%d ",a[i]); } }else{ scanf("%d",&td); T.setL=a[td];T.setR=b[td];T.setN=0; T.set(1,-B,L+F-1); } } return 0; }
做法二:
2)关注到$n$非常小
3)利用map来储存停了车区间,保留区间头尾就好了
4)插入车:遍历map,查看两个停车区间的中间是否可以停下当前这辆车
代码:
#include <bits/stdc++.h> using namespace std; map<int,int>mp; int a[110]; int main(){ int L,B,F,n; scanf("%d%d%d%d",&L,&B,&F,&n); mp[-B]=-B;mp[L+F]=L+F; for(int i=1,op,x;i<=n;++i){ scanf("%d%d",&op,&x); if(op==1){ a[i]=-1; for(auto it1=mp.begin(),it2=++mp.begin();it2!=mp.end();++it1,++it2) { if(it2->first - it1->second >=B+x+F) { a[i]=it1->second + B; mp[a[i]]=a[i]+x; break; } } printf("%d ",a[i]); }else mp.erase(a[x]); } return 0; }