您的位置:首页 > 其它

CodeForces 46D Parking Lot (线段树区间合并)

2016-07-25 22:54 302 查看
题意:

长为len的停车场,一辆车要停下,则必须车尾留b长度的空间且车头与前面的车保持f长度。

有n次操作:1,长为val 的车要寻找车位停下,若能停下输出最小的停车点下标,否则输出-1

                    2,第val辆车开走了。

解:显然是线段树的区间合并。这里有个小技巧,就是树的范围是(-b,len+f-1).这里就保证了第一辆车停在0点,不用特判边界条件。为什么是len+f-1而不是len+f呢?因为,我的做法是这个点代表单位长度 ,0点也表示长度。

#include<iostream>
#include<string>
#include<stdio.h>
#include<string.h>
#include<vector>
#include<math.h>
#include<queue>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
#define LL long long
const int INF=0x3f7f7f7f;
const int MAXN=101005;
const double eps = 1e-10;
struct node
{
int l,r,ll,rr,mx,c;
}tr[MAXN*4];
struct point
{
int l,r;

}a[MAXN];
void pushup(int id);
int max(int x,int y,int z)
{
return max(x,max(y,z));
}
void build(int id,int l,int r)
{
tr[id].l=l;
tr[id].r=r;
tr[id].c=0;
if(l==r)
{
tr[id].ll=tr[id].rr=tr[id].mx=1;
}
else
{
int mid=(l+r)>>1;
build(id*2,l,mid);
build(id*2+1,mid+1,r);
pushup(id);
}
}
void pushup(int id)
{
tr[id].ll=tr[id*2].ll;
tr[id].rr=tr[id*2+1].rr;
if(tr[id].ll==tr[id*2].r-tr[id*2].l+1)tr[id].ll+=tr[id*2+1].ll;
if(tr[id].rr==tr[id*2+1].r-tr[id*2+1].l+1)tr[id].rr+=tr[id*2].rr;
tr[id].mx=max(tr[id*2].mx,tr[id*2+1].mx,tr[id*2].rr+tr[id*2+1].ll);
}
void pushdown(int id)
{
tr[id*2].c=tr[id*2+1].c=1;
tr[id].c=0;
if(tr[id].mx)
{
tr[id*2].ll=tr[id*2].rr=tr[id*2].mx=tr[id*2].r-tr[id*2].l+1;
tr[id*2+1].ll=tr[id*2+1].rr=tr[id*2+1].mx=tr[id*2+1].r-tr[id*2+1].l+1;
}
else
{
tr[id*2].ll=tr[id*2].rr=tr[id*2].mx=0;
tr[id*2+1].ll=tr[id*2+1].rr=tr[id*2+1].mx=0;
}

}
int quary(int id,int mx)
{
if(tr[id].l==tr[id].r)
{
return tr[id].l;
}
else
{
//int mid=(tr[id].l+tr[id].r)/2;
if(tr[id].c)pushdown(id);
if(mx<=tr[id*2].mx)return quary(id*2,mx);
else if(mx<=tr[id*2].rr+tr[id*2+1].ll)
{
return tr[id*2].r-tr[id*2].rr+1;
}
else
{
return quary(id*2+1,mx);
}
}
}
void update(int id,int l,int r,int val)
{
if(l<=tr[id].l&&tr[id].r<=r)
{
tr[id].c=1;
if(val==0)
tr[id].ll=tr[id].rr=tr[id].mx=tr[id].r-tr[id].l+1;
else
tr[id].ll=tr[id].rr=tr[id].mx=0;
}
else
{
int mid=(tr[id].l+tr[id].r)>>1;
if(tr[id].c)pushdown(id);
if(r<=mid)update(id*2,l,r,val);
else if(l>mid)update(id*2+1,l,r,val);
else
{
update(id*2,l,r,val);
update(id*2+1,l,r,val);

}
pushup(id);
}
}
int main()
{
int len,i,q,b,f;
while(scanf("%d%d%d%d",&len,&b,&f,&q)!=EOF)
{
build(1,-b,len+f-1);
int cnt=0;
for(i=1;i<=q;i++)
{
int op,val;
scanf("%d%d",&op,&val);
if(op==1)
{
if(tr[1].mx<(val+b+f))
{
puts("-1");
a[i].l=-1;
a[i].r=-1;
continue;
}
int ans=quary(1,val+b+f);
printf("%d\n",ans+b);
a[i].l=ans+b;
a[i].r=ans+b+val-1;
update(1,a[i].l,a[i].r,1);
}
else
{
a[i].l=-1;
a[i].r=-1;
update(1,a[val].l,a[val].r,0);
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: