题意:在一条直线上停车,要求新停入的车有最小前后距离限制(头尾不算),支持停车和开走。
思路:在直线头尾加入一段虚拟的长度,使头尾部不用特殊处理,查询时加入前后距离限制,增删时只计原长。
做完这题,对线段树的理解又清晰了一些。目前遇到的基本都是点树,每个节点维护的是点的数目。所以在询问长度时,头尾需要各缩减1,因为和其他区间相连处会有一个长度为1的半开区间部分,不需要计在节点数内。
原来题目的操作2指的是开走第x个操作的车,在这里WA了一次,蛋疼。题目的数据规模才100,暴力的话复杂度也就1e7。。是不是可以乱搞呢(¯﹃¯)
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define ls (rt<<1)
#define rs (rt<<1|1)
const int MAXN = 101000;
int lpa[MAXN<<2],rpa[MAXN<<2],mpa[MAXN<<2];
int cover[MAXN<<2];
struct Q{
int l,r;
}que[MAXN];
int p;
int max(int a,int b) { return a>b?a:b; }
void build(int l, int r, int rt)
{
cover[rt] = 0;
lpa[rt] = rpa[rt] = mpa[rt] = r-l+1;
}
void pushdown(int m, int len, int rt)
{
if(cover[rt] != -1)
{
lpa[ls] = rpa[ls] = mpa[ls] = cover[rt]? 0 : len-(len>>1);
lpa[rs] = rpa[rs] = mpa[rs] = cover[rt]? 0 : (len>>1);
cover[ls] = cover[rs] = cover[rt];
cover[rt] = -1;
}
}
void pushup(int m, int len, int rt)
{
lpa[rt] = lpa[ls];
rpa[rt] = rpa[rs];
if(lpa[rt] == len-(len>>1)) lpa[rt] += lpa[rs];
if(rpa[rt] == (len>>1)) rpa[rt] += rpa[ls];
mpa[rt] = rpa[ls] + lpa[rs];
mpa[rt] = max(mpa[rt], max(lpa[rt], rpa[rt]));
mpa[rt] = max(mpa[rt], max(mpa[ls], mpa[rs]));
if(cover[ls]!=-1 && cover[ls]==cover[rs]) cover[rt] = cover[ls];
else cover[rt] = -1;
}
int query(int len, int l, int r, int rt)
{
if(l == r)
{
return l;
}
else
{
int m = (l+r)>>1;
pushdown(m,r-l+1,rt);
if(mpa[ls] >= len) return query(len, lson);
else if(rpa[ls]+lpa[rs] >= len) return m-rpa[ls]+1;
else return query(len, rson);
}
}
void update(int L, int R, int col, int l, int r, int rt)
{
if(L<=l && r<=R)
{
cover[rt] = col;
lpa[rt] = rpa[rt] = mpa[rt] = col? 0 : r-l+1;
}
else
{
int m = (l+r)>>1;
pushdown(m,r-l+1,rt);
if(L<=m) update(L,R,col,lson);
if(R> m) update(L,R,col,rson);
pushup(m,r-l+1,rt);
}
}
int main()
{
int n,b,f;
int q;
int op,x;
while(~scanf("%d%d%d", &n, &b, &f))
{
build(-b+1,n+f-1,1);
scanf("%d", &q);
p = 0;
while(q--)
{
p ++;
scanf("%d%d", &op, &x);
if(op == 1)
{
// printf("mpa[1] = %d\n", mpa[1]);
if(mpa[1] < x+b+f-1) printf("-1\n");
else
{
int tt = query(x+b+f-1,-b+1,n+f-1,1)+b-1;
printf("%d\n", tt);
update(tt,tt+x,1,-b+1,n+f-1,1);
que[p].l = tt,que[p].r = tt+x;
}
}
else
{
update(que[x].l,que[x].r,0,-b+1,n+f-1,1);
}
}
}
return 0;
}