poj 3667 Hotel

依旧磕磕绊绊 T T 。。还是看大牛们的代码。。。

我表示我对线段树真是感觉不大,稍微难一点的就不会了,肿么办吧。T T 。。

不过看过之后,感觉线段树还是好强大好强大好强大!!!

节点信息:从当前区间的左端点连接的最长空房间,从当前区间右端点连接的最长空房间,以及当前区间的最长空房间。

本来是觉得如果一个区间跨越两个线段不好计算,试想一下,如果有这么一段空区域,那它一定是它的子线段的左子树的从右出发的最长空房间和右子树从左出发的最长空房间的和。知道这个后,就好办多啦。

还要用到 lazy 思想,遇到不同的标记时,往下推进更新即可。


hdu3397也是类似的,但是加了一个区间取反操作,我郁闷好久了。。。没想到太好的解决方法捏。。哎。

#include <queue>
#include <stack>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <limits.h>
#include <string.h>
#include <string>
#include <algorithm>
#define MID(x,y) ( ( x + y ) >> 1 )
#define L(x) ( x << 1 )
#define R(x) ( x << 1 | 1 )
#define BUG puts("here!!!")

using namespace std;

const int MAX = 50010;
struct Tnode{ int l,r,lval,rval,sum,cover;};
Tnode node[MAX<<2];

void init()
{
	memset(node,0,sizeof(node));
}

void Build(int t,int l,int r)
{
	node[t].l = l; node[t].r = r;
	node[t].sum = r - l; node[t].cover = 0;
	node[t].lval = node[t].rval = r - l;
	if( node[t].l == node[t].r - 1 )
		return ;
	int mid = MID(l,r);
	Build(L(t),l,mid);
	Build(R(t),mid,r);
}

void Updata_sum(int t)
{
	if( node[t].cover == 0 )
		node[t].sum = node[t].rval = node[t].lval = node[t].r - node[t].l;
	else
		node[t].sum = node[t].rval = node[t].lval = 0;
}
void Updata_cover(int t)
{
	if( node[L(t)].cover == 0 && node[R(t)].cover == 0 )
		node[t].cover = 0;
	else
		if( node[L(t)].cover == 1 && node[R(t)].cover == 1 )
			node[t].cover = 1;
		else
			node[t].cover = -1;
}
void Updata(int t,int l,int r,int cover)
{
	if( node[t].cover == cover ) return ;
	if( node[t].l >= l && node[t].r <= r )
	{
		node[t].cover = cover;
		Updata_sum(t);
		return ;
	}
	if( node[t].l == node[t].r - 1 ) return ;
	if( node[t].cover != -1 )
	{
		node[R(t)].cover = node[L(t)].cover = node[t].cover;
		Updata_sum(L(t)); Updata_sum(R(t));
	}
	int mid = MID(node[t].l,node[t].r);
	if( l >= mid )
		Updata(R(t),l,r,cover);
	else
		if( r < mid )
			Updata(L(t),l,r,cover);
		else
		{
			Updata(L(t),l,mid,cover);
			Updata(R(t),mid,r,cover);
		}
	Updata_cover(t);
	node[t].lval = node[L(t)].lval + ( node[L(t)].cover == 0 ? node[R(t)].lval : 0 );
	node[t].rval = node[R(t)].rval + ( node[R(t)].cover == 0 ? node[L(t)].rval : 0 );
	node[t].sum = max(max(node[L(t)].sum,node[R(t)].sum),node[R(t)].lval + node[L(t)].rval);
}

int Query(int t,int len)
{
	if( node[t].cover == 0 && node[t].sum >= len )
		return node[t].l;
	if( node[t].cover == 1 ) return -1;
	if( node[t].cover == -1 )
	{
		if( node[L(t)].sum >= len )
			return Query(L(t),len);
		else
			if( node[L(t)].rval + node[R(t)].lval >= len )
				return MID(node[t].l,node[t].r) - node[L(t)].rval;
			else
				return Query(R(t),len);
	}
	return -1;
}

int main()
{
	int n,m,ind,x,y;
	while( ~scanf("%d%d",&n,&m) )
	{
		init();
		Build(1,0,n);
		while( m-- )
		{
			scanf("%d",&ind);
			if( ind == 1 )
			{
				scanf("%d",&x);
				int pos = Query(1,x);
				printf("%d\n",pos+1);
				if( pos != -1 )
					Updata(1,pos,pos+x,1);
			}
			if( ind == 2 )
			{
				scanf("%d%d",&x,&y);
				Updata(1,x-1,x-1+y,0);
			}
		}
	}
return 0;
}


你可能感兴趣的:(poj 3667 Hotel)