—————————————————————分割线——————————————————
题目大意:
有一个长为L的街道,一侧停车,有两种操作
1:将长度为x的车停放到街道上,横坐标尽量小
2:将第x次操作的车开出街道
要求停放的车跟后面的车相距b米,跟前面一辆车相距f米
思路:
建立一个长度为(-b,l+f)的线段树
区间维护:
某个节点左连续的最大区间长度,右连续的最大区间长度,总区间的最大连续长度
对于某次询问查询连续长度为 x+b+f的区间的左端点,先左,再中,再右
这题点表示线段,细节慢慢处理吧,搞了一天多~~~
#include<iostream>
#include<cstring>
#include<cstdio>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int maxn=100001;
using namespace std;
int b,f;
int cover[maxn<<2],lc[maxn<<2],rc[maxn<<2],mc[maxn<<2];
struct node
{
int l,r;
}a[110];
void push_up(int rt,int m)
{
lc[rt]=lc[rt<<1];
rc[rt]=rc[rt<<1|1];
if(lc[rt]==(m-(m>>1))) lc[rt]+=lc[rt<<1|1];
if(rc[rt]==(m>>1)) rc[rt]+=rc[rt<<1];
mc[rt]=max(lc[rt<<1|1]+rc[rt<<1],max(mc[rt<<1],mc[rt<<1|1]));
}
void push_down(int rt,int m)
{
if(cover[rt]!=-1){
cover[rt<<1]=cover[rt<<1|1]=cover[rt];
mc[rt<<1]=lc[rt<<1]=rc[rt<<1]=cover[rt] ? 0:(m-(m>>1));
mc[rt<<1|1]=lc[rt<<1|1]=rc[rt<<1|1]=cover[rt] ? 0:(m>>1);
cover[rt]=-1;
}
}
void build(int l,int r,int rt)
{
cover[rt]=-1;
mc[rt]=lc[rt]=rc[rt]=r-l+1;
if(l==r) return ;
int m=(l+r)>>1;
build(lson);
build(rson);
}
void update(int L,int R,int c,int l,int r,int rt)
{
if(L<=l&&r<=R){
cover[rt]=c;
mc[rt]=lc[rt]=rc[rt]=c ?0:(r-l+1);
return ;
}
push_down(rt,r-l+1);
int m=(l+r)>>1;
if(L<=m) update(L,R,c,lson);
if(m<R) update(L,R,c,rson);
push_up(rt,r-l+1);
}
int query(int x,int l,int r,int rt)
{
if(l==r) return l;
push_down(rt,r-l+1);
int m=(l+r)>>1;
if(mc[rt<<1]>=x) return query(x,lson);
else if(lc[rt<<1|1]+rc[rt<<1]>=x) return m-rc[rt<<1]+1;
else return query(x,rson);
}
int main()
{
int n,m;
scanf("%d %d %d %d",&n,&b,&f,&m);
build(-b,n+f,1);
for(int id=1;id<=m;++id){
int op,x;
scanf("%d %d",&op,&x);
if(op==1){
if(mc[1]<x+b+f+1) printf("-1\n");
else{
int p=query(x+b+f,-b,n+f,1);
p+=b;
printf("%d\n",p);
a[id].l=p,a[id].r=p+x-1;
update(p,p+x-1,1,-b,n+f,1);
}
}
else update(a[x].l,a[x].r,0,-b,n+f,1);
}
return 0;
}