pku 3667 hotel

原创 2013年12月04日 22:28:20

感觉题目不难啊,就是处理有点烦而已。水过了。pku30题留个纪念。

#include<stdio.h>
#include<iostream>
using namespace std;
const int OTHER = 0;
const int FULL = 1;
const int EMPTY = -1;
const int QUERRY = 1;
const int LEAVE = 2;
const int MAX_N = 50050;
const int MAX_T = MAX_N*2;
const int root = 1;
struct node
{
	int L,R;
	int Lid,Rid;
	int value;
	int Lvalue,Rvalue;
	int tag;
};
struct node T[MAX_T];
int N,M;
int times;
struct node Tmaking(int a,int b,int c,int d,int e,int f,int g,int h)
{
	struct node tmp ;
	tmp.L=a;
	tmp.R=b;
	tmp.Lid=c;
	tmp.Rid=d;
	tmp.value=e;
	tmp.Lvalue=f;
	tmp.Rvalue=g;
	tmp.tag=h;
	return tmp;
}
void Build(int l,int r)
{
	if (l==r) {T[++times]=Tmaking(l,r,-1,-1,1,1,1,OTHER);return ;}
	int mid=(l+r)/2;
	int now=++times;
	int lid=times+1;
	Build(l,mid);
	int rid=times+1;
	Build(mid+1,r);
	T[now]=Tmaking(l,r,lid,rid,r-l+1,r-l+1,r-l+1,OTHER);
}
void init()
{
	scanf("%d %d",&N,&M);
	Build(1,N);
}
void lazy_tag(int t)
{
	if (T[t].tag!=OTHER)
	{	
		int l=T[t].L;
		int r=T[t].R;
		int lid=T[t].Lid;
		int rid=T[t].Rid;
		int mid=(l+r)/2; 
		T[lid].tag=T[rid].tag=T[t].tag;
		T[lid].value=T[lid].Lvalue=T[lid].Rvalue=(T[t].tag==FULL?0:mid-l+1);
		T[rid].value=T[rid].Lvalue=T[rid].Rvalue=(T[t].tag==FULL?0:r-mid);
		T[t].tag=OTHER;
	}
}
void change(int t,int s,int e,int tagf)
{
	int l=T[t].L;
	int r=T[t].R;
	int lid=T[t].Lid;
	int rid=T[t].Rid;
	int mid=(l+r)/2; 
	int atag= (tagf==FULL?0:r-l+1);
	if (s<=l&&e>=r) {T[t]=Tmaking(l,r,lid,rid,atag,atag,atag,tagf);return ;}
	lazy_tag(t);
	if (e<=mid) change(lid,s,e,tagf);
	else if (s>mid) change(rid,s,e,tagf);
	else change(lid,s,mid,tagf),change(rid,mid+1,e,tagf);
	int value = max(T[lid].value,T[rid].value);
	value=max(value,T[lid].Rvalue+T[rid].Lvalue);
	int lvalue = T[lid].Lvalue;
	if (lvalue==mid-l+1) lvalue+=T[rid].Lvalue;
	int rvalue = T[rid].Rvalue;
	if (rvalue==r-mid) rvalue+=T[lid].Rvalue;
	T[t]=Tmaking(l,r,lid,rid,value,lvalue,rvalue,OTHER);
}
int Querry(int t,int room)
{
	if (T[t].value<room) return 0;
	int l=T[t].L;
	int r=T[t].R;
	int lid=T[t].Lid;
	int rid=T[t].Rid;
	int mid=(l+r)/2;
	lazy_tag(t);
	int pos;
	pos=Querry(lid,room);
	if (pos) return pos;
	if (T[lid].Rvalue+T[rid].Lvalue>=room) pos=mid-T[lid].Rvalue+1;
	if (pos) return pos;
	pos=Querry(rid,room);
	if (pos) return pos;
	return 0;
}
void work_put()
{
	int op,a,b,i;
	int pos;
	for (i=1;i<=M;i++)
	{
		scanf("%d",&op);
		if (op==QUERRY)
		{
			scanf("%d",&a);
			pos=Querry(root,a);
			printf("%d\n",pos);
			if (pos) change(root,pos,pos+a-1,FULL);
		}
		if (op==LEAVE)
		{
			scanf("%d %d",&a,&b);
			change(root,a,a+b-1,EMPTY);
		}
	}
}
int main()
{
	init();
	work_put();
	return 0;
}


 

POJ3667-Hotel-线段树区间合并(模板)

题目链接:http://poj.org/problem?id=3667 线段树真是牛逼啊,这么多的功能。。。 这是个线段树维护区间合并的问题;我们要维护一个区间的从左端点开始的最长区间,右端点的最...
  • wlxsq
  • wlxsq
  • 2015年08月06日 09:52
  • 836

poj 3667Hotel(经典线段树)

题目大意: 有N个房间排在一列,有两种操作。 1:查询最靠左的长度为len的空房间,并且入住这些空房间。 2:以l开头,长度为r的房间退房。(如果本来就是空的 还是要退房)。...
  • tsxhl111
  • tsxhl111
  • 2014年11月12日 15:41
  • 546

【POJ】3667-Hotel(线段树的区间合并)

标记线段树的时候利用 lsum rsum msum 记录最左边 zui右边 以及整个区间的最大连续空位的值 维护的时候注意合并#include #include #include using nam...
  • u013451221
  • u013451221
  • 2015年04月27日 16:02
  • 620

POJ 3667 hotel 和 NYOJ 537 hotel 【线段树之区间合并】

原题连接:http://poj.org/problem?id=3667 题意:参考样例,第一行输入n,m ,n代表有n个房间,编号为1---n,开始都为空房,m表示以下有m行操作,以下 每行先输入一...
  • PIAOYI0208
  • PIAOYI0208
  • 2012年11月05日 18:58
  • 3605

线段树专题—POJ 3667 Hotel(区间合并模板)

题意:给一个n和m,表示n个房间,m次操作,操作类型有2种,一种把求连续未租出的房间数有d个的最小的最左边的房间号,另一个操作时把从x到x+d-1的房间号收回。 分析:这是一个区间合并的典型...
  • sin_XF
  • sin_XF
  • 2015年08月15日 14:47
  • 756

3667 Hotel

HotelTime Limit: 3000MS Memory Limit: 65536KTotal Submissions: 2523 Accepted: 957DescriptionThe cows...
  • hqd_acm
  • hqd_acm
  • 2010年07月22日 11:37
  • 800

poj 3667 Hotel(线段树)

poj 3667 Hotel 题目大意:给定一个区间,两种操作: 1 x:找到区间中最左边,将长度为x的区间放入,要求尽量靠左。2 l r:清空l,r + l - 1这段区间。 解题...
  • u011328934
  • u011328934
  • 2014年09月28日 10:18
  • 474

POJ - 3667 Hotel

POJ - 3667  Hotel The cows are journeying north to Thunder Bay in Canada to gain cultural enrichmen...
  • kele52he
  • kele52he
  • 2017年07月04日 21:33
  • 121

PKU 3667

线段树题, 操作有:    1. 找到线段树中从左数第一段长度大于等于L的连续的0, 返回这段0的左边第一个元素的下标, 如果没有返回0.    2. 更新一段区间, 使这段区间全为0或者全为1.从上...
  • RaceBug2010
  • RaceBug2010
  • 2011年07月29日 13:18
  • 536

POJ 3667 Hotel (线段树)

题目类型  线段树 题目意思 给出最多50000个房间 最多有50000个操作 操作1 安排x个连续的空房间 (尽量安排靠前的,如果不能安排输出0) 并输出安排的第1个房间的编号...
  • Yunyouxi
  • Yunyouxi
  • 2014年12月01日 22:28
  • 287
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:pku 3667 hotel
举报原因:
原因补充:

(最多只允许输入30个字)