POJ 3667 - Hotel

Description

The cows are journeying north to Thunder Bay in Canada to gain cultural enrichment and enjoy a vacation on the sunny shores of Lake Superior. Bessie, ever the competent travel agent, has named the Bullmoose Hotel on famed Cumberland Street as their vacation residence. This immense hotel has N (1 ≤ N ≤ 50,000) rooms all located on the same side of an extremely long hallway (all the better to see the lake, of course).

The cows and other visitors arrive in groups of size Di (1 ≤Di ≤ N) and approach the front desk to check in. Each group i requests a set of Di contiguous rooms from Canmuu, the moose staffing the counter. He assigns them some set of consecutive room numbersr..r+Di-1 if they are available or, if no contiguous set of rooms is available, politely suggests alternate lodging. Canmuu always chooses the value ofr to be the smallest possible.

Visitors also depart the hotel from groups of contiguous rooms. Checkout i has the parameters Xi andDi which specify the vacating of rooms Xi ..Xi +Di-1 (1 ≤XiN-Di+1). Some (or all) of those rooms might be empty before the checkout.

Your job is to assist Canmuu by processing M (1 ≤ M < 50,000) checkin/checkout requests. The hotel is initially unoccupied.

Input

* Line 1: Two space-separated integers: N and M
* Lines 2..M+1: Line i+1 contains request expressed as one of two possible formats: (a) Two space separated integers representing a check-in request: 1 andDi (b) Three space-separated integers representing a check-out: 2,Xi, and Di

Output

* Lines 1.....: For each check-in request, output a single line with a single integerr, the first room in the contiguous sequence of rooms to be occupied. If the request cannot be satisfied, output 0.

Sample Input

10 6
1 3
1 3
1 3
1 3
2 5 5
1 6


Sample Output

1
4
7
0
5


#include <stdio.h>

const int maxn = 50000;
int sum[maxn*3], lsum[maxn*3], rsum[maxn*3], sym[maxn*3];

void BuildTree(int left, int right, int root);
void UpData(int L, int R, int c, int left, int right, int root);
void PushDown(int root, int k);
void PushUp(int root, int k);
int query(int w, int left, int right, int root);
int Max(int x, int y)
{
return x>y ? x:y;
}

int main()
{
int n, mNum, op, a, b;
scanf("%d %d", &n, &mNum);

BuildTree(1, n, 1);
for (int i=1; i<=mNum; ++i)
{
scanf("%d", &op);
if (op == 1)
{
scanf("%d", &a);
if (sum[1] < a)
printf("0\n");
else
{
int pos = query(a, 1, n, 1);
printf("%d\n", pos);
UpData(pos, pos+a-1, 1, 1, n, 1);
}
}
else
{
scanf("%d %d", &a, &b);
UpData(a, a+b-1, 0, 1, n, 1);
}
}
return 0;
}

void BuildTree(int left, int right, int root)
{
sym[root] = -1;
lsum[root] = rsum[root] = sum[root] = right-left+1;
if (left == right)
return;

int mid = (left+right)>>1;
BuildTree(left, mid, root << 1);
BuildTree(mid+1, right, root << 1|1);
}

int query(int w, int left, int right, int root)
{
if (left == right)
return 1;

PushDown(root, right-left+1);

int mid = (left+right)>>1;
if (w <= sum[root<<1])
return query(w, left, mid, root << 1);
else if (rsum[root<<1] + lsum[root<<1|1] >= w)
return mid - rsum[root<<1]+1;
else
return query(w, mid+1, right, root << 1|1);
}

void UpData(int L, int R, int c, int left, int right, int root)
{
if (L <= left && right <= R)
{
lsum[root] = rsum[root] = sum[root] = c ? 0 : right-left+1;
sym[root] = c;
return;
}

PushDown(root, right-left+1);

int mid = (right+left)>>1;
if (L <= mid)
UpData(L, R, c, left, mid, root << 1);
if (mid < R)
UpData(L, R, c, mid+1, right, root << 1|1);

PushUp(root, right-left+1);
}

void PushUp(int root, int k)
{
lsum[root] = lsum[root << 1];
rsum[root] = rsum[root << 1|1];

if (lsum[root] == k-(k>>1))
lsum[root] += lsum[root << 1|1];
if (rsum[root] == k>>1)
rsum[root] += rsum[root << 1];

sum[root] = Max(rsum[root << 1] + lsum[root << 1|1], Max(sum[root << 1], sum[root << 1|1]));
}

void PushDown(int root, int k)
{
if (sym[root] != -1)
{
sym[root << 1] = sym[root << 1|1] = sym[root];
lsum[root << 1] = rsum[root << 1] = sum[root << 1] = sym[root] ? 0:(k-(k>>1));
lsum[root << 1|1] = rsum[root << 1|1] = sum[root << 1|1] = sym[root] ? 0:(k>>1);
sym[root] = -1;
}
}


• 本文已收录于以下专栏：

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

• wlxsq
• 2015年08月06日 09:52
• 840

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

• PIAOYI0208
• 2012年11月05日 18:58
• 3616

poj 3667Hotel(经典线段树)

• tsxhl111
• 2014年11月12日 15:41
• 546

线段树专题—POJ 3667 Hotel（区间合并模板）

• sin_XF
• 2015年08月15日 14:47
• 761

【POJ】3667-Hotel（线段树的区间合并）

• u013451221
• 2015年04月27日 16:02
• 620

poj 3667 Hotel(线段树)

poj 3667 Hotel 题目大意：给定一个区间，两种操作： 1 x：找到区间中最左边，将长度为x的区间放入，要求尽量靠左。2 l r：清空l，r + l - 1这段区间。 解题...
• 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
• 2017年07月04日 21:33
• 125

【线段树】 POJ 3667 Hotel

• blankcqk
• 2014年06月20日 20:47
• 209

POJ 3667 Hotel 线段树

• zhengweijian15
• 2014年02月21日 16:25
• 316

POJ 3667 Hotel (线段树)

• Yunyouxi
• 2014年12月01日 22:28
• 291

举报原因： 您举报文章：POJ 3667 - Hotel 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)