pku 3667 hotel

感觉题目不难啊,就是处理有点烦而已。水过了。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;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值