CodeForces 46D 停车场
Time Limit:2000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u
Description
有一个长为L的停车道,坐标从0开始,车辆停放时车头朝向正方向,且距离车头f范围内和距离车尾b范围内不能有其它车辆。
有两种操作:“1 a”,有1辆长度为a的车开进来找停车位。如果能找到输出最小的起始位置,否则输出-1.
“2 a”,第i个操作中开进来的车开出去了(保证第i个操作是1操作)
Input
第一行3个 整数L,b 和f(10 ≤ L ≤ 100000, 1 ≤ b, f ≤ 100).
第二行1个 整数n(1 ≤ n ≤ 100)表示询问个数。
然后n个询问。
Output
每个"1 a"询问输出一个数字占一行。如果没有停车位输出-1,否则输出车尾的坐标(坐标从0开始)。
Sample Input
30 1 2 6 1 5 1 4 1 5 2 2 1 5 1 4 30 1 1 6 1 5 1 4 1 5 2 2 1 5 1 4 10 1 1 1 1 12
Sample Output
0 6 11 17 23 0 6 11 17 6 -1 解题思路: 这题和hotle相似,几乎就是改改代码就对了,可以之前我还没发现,自己写了半天老是首尾处理不好 然后别人提醒我直接在长度首尾添加上车的前后距离就可以了,真是,这样简单多了,反正首部一定 要放车,尾部也可以正常处理。 1,这题的主要的目的就是让你找到一个最靠左的距离,停一部指定距离的车,满足车前车后的距离 2,若成功停车就返回车尾的位置,否则返回-1 3,然后就是通过线段树找位置咯,找到满足这样长度的区间,线段树要做的就是区间合并维护空位 4,然后细心一点咯。#include<iostream> #include<cstdio> #include<cstring> using namespace std; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 const int maxn = 100005 ; int tlen[maxn<<2] ;///tlen表示该区间可用的区间的最大长度 int rlen[maxn<<2] ;///rlen表示一个区间从最右端开始可用的且连续的最大长度 int llen[maxn<<2] ;///llen表示一个区间从最左端开始可用的且连续的最大长度 int setv[maxn<<2] ; struct node{ int op ; int x; int l; int r; }; void pushdown(int l,int r,int rt){ if(setv[rt]!=-1){ setv[rt<<1] = setv[rt] ; setv[rt<<1|1] = setv[rt] ; int m = (l+r)>>1 ; tlen[rt<<1] = llen[rt<<1] = rlen[rt<<1] = setv[rt]*(m-l+1) ; tlen[rt<<1|1] = llen[rt<<1|1] = rlen[rt<<1|1] = setv[rt]*(r-m) ; setv[rt] = -1 ; } return ; } void pushup(int l,int r,int rt){ int m = (l+r)>>1 ; if(llen[rt<<1]==(m-l+1))llen[rt] = llen[rt<<1]+llen[rt<<1|1]; else llen[rt] = llen[rt<<1] ; if(rlen[rt<<1|1]==(r-m))rlen[rt] = rlen[rt<<1|1]+rlen[rt<<1] ; else rlen[rt] = rlen[rt<<1|1] ; tlen[rt] = max(tlen[rt<<1],tlen[rt<<1|1]); tlen[rt] = max(tlen[rt],rlen[rt<<1]+llen[rt<<1|1]); return ; } void build(int l,int r,int rt){ int m = (l+r)>>1 ; if(l==r){ tlen[rt] = 1 ; llen[rt] = 1 ; rlen[rt] = 1 ; return ; } build(lson) ; build(rson) ; pushup(l,r,rt) ; } int query(int p,int l,int r,int rt ){///找p个连续座位 if(l==r){ return l; } int m = (r+l)>>1 ; pushdown(l,r,rt) ; if(tlen[rt]>=p){ if(tlen[rt<<1]>=p){ return query(p,lson) ; }else if(rlen[rt<<1]+llen[rt<<1|1]>=p){//&&rlen[rt<<1]>0){ //return query(min(p,rlen[rt<<1]),lson) ; return m-rlen[rt<<1]+1 ; }else{ return query(p,rson) ; } //return 0; }else{ return 0; } } void update(int L,int R,int s,int l,int r,int rt){ if(L<=l&&r<=R){ setv[rt] = s ; tlen[rt] = llen[rt] = rlen[rt] = s*(r-l+1) ; return ; } pushdown(l,r,rt) ; int m = (l+r)>>1 ; if(L<=m)update(L,R,s,lson) ; if(R>m)update(L,R,s,rson) ; pushup(l,r,rt) ; } node arry[115] ; int L,b,f ; int main(){ int n,m; //freopen("in.txt","r",stdin) ; //freopen("out2.txt","w",stdout) ; while(~scanf("%d%d%d",&L,&b,&f)){ memset(tlen,0,sizeof(tlen)) ; memset(rlen,0,sizeof(rlen)) ; memset(llen,0,sizeof(llen)) ; memset(setv,-1,sizeof(setv)) ; build(1,L+b+f,1) ; n = L+b+f ; scanf("%d",&m); for(int i=0;i<m;i++){ scanf("%d%d",&arry[i].op,&arry[i].x); } for(int i=0;i<m;i++){ if(arry[i].op==1){ int w = arry[i].x+b+f; if(w>tlen[1]){ puts("-1") ; continue ; } int index = query(w,1,n,1) ; printf("%d\n",index-1); arry[i].l = index+b ; arry[i].r = index+b+arry[i].x ; if(index!=0){ update(index+b,index+b+arry[i].x-1,0,1,n,1) ; } }else{ update(arry[arry[i].x-1].l,arry[arry[i].x-1].r,1,1,n,1) ; } } } return 0; }