标签:
题目大意:Hotel有N(1 ≤ N ≤ 50,000)间rooms,并且所有的rooms都是连续排列在同一边,groups需要check in 房间,要求房间的编号为连续的r..r+Di-1并且r是最小的;visitors同样可能check out,并且他们每次check out都是编号为Xi ..Xi +Di-1 (1 ≤ Xi ≤ N-Di+1)的房间,题目的输入有两种样式:
要求对于每次request,输出为groups分配数目为a的房间中编号最小的房间编号
维护几个数据:该区间最大连续长度,从左边第一个开始的最大连续长度lmax,从右边开始的最大连续长度rmax,是否颜色一样(是某个颜色)tong;
然后a[root*2].rmax+a[root*2+1].lmax就是中间部分的长度,一些细节比较难以处理,要注意一下。
这题和POJ3368真的太像了,简直是孪生兄弟。
本题的重点是如何处理中间接起来的问题,当然3368也是。
具体就看代码吧:
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<math.h>
#include<stdlib.h>
using namespace std;
struct pai
{
int left, right, lmax, rmax, zmax, tong,col;
}a[50000*4+20];
struct PP
{
int left; int right;
}o;
void up(int root)
{
int tmax;
if (a[root * 2].tong==1 && a[root * 2 + 1].tong==1)//说明房间还有,这里很可能有问题,脑子乱
{
a[root].tong = 1;
}
a[root].rmax = a[root * 2 + 1].rmax;
a[root].lmax = a[root * 2].lmax;
if (a[root * 2].rmax && a[root * 2 + 1].lmax)
{
if (a[root * 2 + 1].tong==1)
{
tmax = a[root * 2 + 1].zmax + a[root * 2].rmax;
a[root].rmax = tmax;
}
if (a[root * 2].tong==1)
{
tmax = a[root * 2].zmax + a[root * 2 + 1].lmax;
a[root].lmax = tmax;
}
tmax = a[root * 2].rmax + a[root * 2 + 1].lmax;
}
else
{
tmax = -1;
}
int max1 = a[root * 2].zmax;
int max2 = a[root * 2 + 1].zmax;
int max3 = max(max1, max2);
max3 = max(tmax, max3);
a[root].zmax = max3;
}
void down(int root)
{
if (a[root].tong == 0)
{
a[root * 2].lmax =a[root*2].rmax=a[root*2].zmax= 0;
a[root * 2+1].lmax = a[root * 2+1].rmax = a[root * 2+1].zmax = 0;
a[root * 2].tong = a[root * 2 + 1].tong = 0;
a[root].tong = 7;
}
if (a[root].tong == 1)
{
a[root * 2].lmax = a[root * 2].rmax = a[root * 2].zmax = a[root * 2].right - a[root * 2].left + 1;
a[root * 2 + 1].lmax = a[root * 2 + 1].rmax = a[root * 2 + 1].zmax = a[root * 2+1].right - a[root * 2+1].left + 1;
a[root * 2].tong = a[root * 2 + 1].tong = 1;
a[root].tong = 7;
}
}
void build(int left, int right, int root)
{
a[root].left = left;
a[root].right = right;
if (left == right)
{
a[root].lmax = 1;
a[root].rmax = 1;
a[root].lmax = 1;
a[root].zmax = 1;
a[root].tong = 1;
a[root].col = 1;
return;
}
int m = (left + right) / 2;
build(left, m, root * 2);
build(m + 1, right, root * 2 + 1);
up(root);
}
int search(int left, int right, int root,int x)
{
if (a[root].zmax < x)
{
return -1;
}
if (a[root * 2].lmax >= x)
{
o.left = a[root * 2].left;
o.right = a[root * 2].left + x - 1;
return o.left;
}
if (a[root * 2].zmax >= x)
{
return search(a[root * 2].left, a[root * 2].right, root * 2, x);
}
if ((a[root * 2].rmax + a[root * 2 + 1].lmax) >= x)
{
o.left = a[root * 2].right - a[root * 2].rmax + 1;//这里有可能不对
o.right = o.left + x - 1;
return o.left;
}
return search(a[root * 2 + 1].left, a[root * 2 + 1].right, root * 2 + 1, x);
}
void change(int left, int right, int root, int x)
{
if (a[root].left >= left && a[root].right <= right)
{
a[root].lmax = a[root].rmax = a[root].zmax=a[root].tong = 0;//tong先没搞
return;
}
down(root);
int m = (a[root].left + a[root].right) / 2;
if (left <= m)
{
change(left, right, root * 2, x);
}
if (right > m)
{
change(left,right, root * 2+1, x);
}
up(root);
}
void change2(int left, int right, int root, int x)
{
if (a[root].left >= left && a[root].right <= right)
{
a[root].lmax = a[root].rmax = a[root].zmax=a[root].right-a[root].left+1;
a[root].tong = 1;
return;
}
down(root);
int m = (a[root].left + a[root].right) / 2;
if (left <= m)
{
change2(left, right, root * 2, x);
}
if (right > m)
{
change2(left, right, root * 2 + 1, x);
}
up(root);
}
int main()
{
int i,j,n, m,temp,b,c,temp2;
while (~scanf("%d%d", &n, &m))
{
build(1, n, 1);
for (i = 0; i < m; i++)
{
scanf("%d", &temp);
if (temp == 1)
{
scanf("%d", &b);
temp2=search(1, n, 1, b);
if (temp2 != -1)
{
cout << temp2 << endl;
}
else
{
cout << '0' << endl;
continue;
}
change(o.left, o.right, 1, 0);
}
else
{
scanf("%d%d", &b, &c);
change2(b,b+c-1, 1, 1);
}
}
}
}标签:
原文地址:http://blog.csdn.net/nie8484/article/details/45045985