Codeforces Beta Round #43 D. Parking Lot

及其类似POJ 3667 hotel,这个题我一直没忘。。囧。。

不过这个题稍微简单点。

停车位,停一辆车需要连续的一段和,其中包括与前面车的间距和与后面车的间距(方便倒车),在路端的车可以不用考虑前方距离。

这样的话,把路扩长 b + f ,这样的话,就不用考虑路端情况了,统一处理就好。。。

然后直接查找空位(len + b + f),然后更新车长的那段(len)即可。

不用lazy标记,因为都是成段更新,用lazy标记会很鸡肋。。、

#include <set>
#include <map>
#include <queue>
#include <stack>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
#include <string>
#include <algorithm>
#include <iostream>
#define MID(x,y) ( ( x + y ) >> 1 )
#define L(x) ( x << 1 )
#define R(x) ( x << 1 | 1 )
#define FOR(i,s,t) for(int i=(s); i<(t); i++)
#define BUG puts("here!!!")
#define STOP system("pause")
#define file_r(x) freopen(x, "r", stdin)
#define file_w(x) freopen(x, "w", stdout)

using namespace std;

const int MAX = 100500;
struct Tnode{				// 一维线段树 
    int l,r, lval, rval, mval, max, cover;
    int len() { return r - l;}
    int mid() { return MID(l,r);}
    bool in(int ll,int rr) { return l >= ll && r <= rr; }
    void lr(int ll,int rr){ l = ll; r = rr;}
};
Tnode node[MAX<<2];

void Build(int t,int l,int r)
{
	node[t].lr(l,r);
	node[t].lval = node[t].rval = node[t].mval = node[t].max = r - l;
	if( node[t].len() == 1 ) return ;
	int mid = MID(l,r);
	Build(L(t),l,mid);
	Build(R(t),mid,r);
}

void Updata_val(int t)
{
	node[t].lval = node[L(t)].lval;
	if( node[L(t)].lval == node[L(t)].len() )
		node[t].lval += node[R(t)].lval;
	
	node[t].rval = node[R(t)].rval;
	if( node[R(t)].rval == node[R(t)].len() )
		node[t].rval += node[L(t)].rval;
	
	node[t].mval = node[L(t)].rval + node[R(t)].lval;
	
	node[t].max = max(node[L(t)].max, node[R(t)].max);
	node[t].max = max(node[t].max, max(node[t].lval, max(node[t].rval, node[t].mval)));
}
void Updata(int t,int l,int r,int val)
{
	if( node[t].in(l,r) )
	{
		node[t].lval = node[t].rval = node[t].mval = node[t].max = (val ? 0 : node[t].len());
		return ;
	}
	if( node[t].len() == 1 ) return ;
	int mid = node[t].mid();
	if( l < mid ) Updata(L(t),l,r,val);
	if( r > mid ) Updata(R(t),l,r,val);
	Updata_val(t);
}

void Query(int t, int len, int &pos)
{
	if( node[t].max == node[t].len() && node[t].max >= len )
	{
		pos = node[t].l;
		return ;
	}
	if( node[t].max < len ) return ;
	if( node[t].len() == 1 ) return ;
	if( node[L(t)].max >= len )
		Query(L(t), len, pos);
	else
		if( node[t].mval >= len )
		{
			pos = node[L(t)].r - node[L(t)].rval;
			return ;
		}
		else
			if( node[R(t)].max >= len )
				Query(R(t), len, pos);
}
struct NODE
{
	int len, pos;
};
NODE a[110];

int main()
{
	int l, b, f, n, cnt, pos, op, len;
	
	while( ~scanf("%d%d%d", &l, &b, &f) )
	{
		scanf("%d", &n);
		Build(1, -b, l + f);
		FOR(i, 1, n+1)
		{
			scanf("%d%d", &op, &len);
			if( op == 1 )
			{
				a[i].len = len;
				pos = -1000;
				Query(1, len+b+f, pos);
				if( pos == -1000 )
				{
					puts("-1");
					a[i].pos = -1;
				}
				else
				{
					printf("%d\n", pos+b);
					a[i].pos = pos + b;
				}
				if( pos != -1000 )
					Updata(1, pos + b, pos + b + len, 1);
			}
			else
			{
				pos = a[len].pos;
				Updata(1, pos, pos + a[len].len, 0);
			}
		}
	}
	
return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值