题意: 有一条长度为L的街道,有N个操作,操作有两种,(1)"1 a",表示有一辆长度为a的车开进来想找停车位,停车位必须满足与它前面的车距离至少为b,与后面的车距离至少为f.如果能找到这样的停车位,输出这辆车的起始位置(且这个位置最小),否则输出-1。(2)"2 a",表示第a个事件里进来停车的那辆车开出去了。
建立起点为-b,终点为L+f的线段树,查找的时候,直接查找len+n+f的线段就可以了。其他的操作跟poj 3667 Hotel类似。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
#define LL(x) (x<<1)
#define RR(x) (x<<1|1)
#define MID(a,b) (a+((b-a)>>1))
const int N=100005;
struct node
{
int lft,rht;
int lmx,rmx,mx,flag;
int len(){return rht-lft;}
int mid(){return MID(lft,rht);}
void init(){lmx=rmx=mx=len();}
void fun(int valu)
{
if(valu==1) lmx=rmx=mx=0;
else lmx=rmx=mx=len();
flag=valu;
}
};
int n,m,b,f;
int st[N],ed[N];
struct Segtree
{
node tree[N*4];
void down(int ind)
{
if(tree[ind].flag)
{
tree[LL(ind)].fun(tree[ind].flag);
tree[RR(ind)].fun(tree[ind].flag);
tree[ind].flag=0;
}
}
void up(int ind)
{
tree[ind].lmx=tree[LL(ind)].lmx;
tree[ind].rmx=tree[RR(ind)].rmx;
tree[ind].mx=max(tree[LL(ind)].mx,tree[RR(ind)].mx);
if(tree[LL(ind)].lmx==tree[LL(ind)].len())
tree[ind].lmx+=tree[RR(ind)].lmx;
if(tree[RR(ind)].rmx==tree[RR(ind)].len())
tree[ind].rmx+=tree[LL(ind)].rmx;
tree[ind].mx=max(tree[ind].mx,tree[LL(ind)].rmx+tree[RR(ind)].lmx);
tree[ind].mx=max(tree[ind].mx,max(tree[ind].lmx,tree[ind].rmx));
}
void build(int lft,int rht,int ind)
{
tree[ind].lft=lft; tree[ind].rht=rht;
tree[ind].flag=0; tree[ind].init();
if(lft+1!=rht)
{
int mid=tree[ind].mid();
build(lft,mid,LL(ind));
build(mid,rht,RR(ind));
}
}
void updata(int st,int ed,int ind,int valu)
{
int lft=tree[ind].lft,rht=tree[ind].rht;
if(st<=lft&&rht<=ed) tree[ind].fun(valu);
else
{
down(ind);
int mid=tree[ind].mid();
if(st<mid) updata(st,ed,LL(ind),valu);
if(ed>mid) updata(st,ed,RR(ind),valu);
up(ind);
}
}
int query(int valu,int ind)
{
down(ind);
int pos;
if(tree[LL(ind)].mx>=valu) pos=query(valu,LL(ind));
else if(tree[LL(ind)].rmx+tree[RR(ind)].lmx>=valu)
pos=tree[LL(ind)].rht-tree[LL(ind)].rmx;
else pos=query(valu,RR(ind));
up(ind);
return pos;
}
}seg;
int main()
{
while(scanf("%d%d%d%d",&n,&b,&f,&m)!=EOF)
{
seg.build(-b,n+f,1);
for(int i=1;i<=m;i++)
{
int cmd,len,pos=-1;
scanf("%d%d",&cmd,&len);
if(cmd==1)
{
if(seg.tree[1].mx>=len+b+f)
{
pos=seg.query(len+b+f,1)+b;
st[i]=pos,ed[i]=pos+len;
seg.updata(st[i],ed[i],1,1);
}
printf("%d\n",pos);
}
else
{
seg.updata(st[len],ed[len],1,-1);
}
}
}
return 0;
}