POJ 3667 Hotel

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <string>
using namespace std;

int n, m;

const int maxn = 55555;

#define lc o*2
#define rc o*2+1

int lsum[maxn<<2], rsum[maxn<<2], msum[maxn<<2];

int cover[maxn<<2];

void build(int o, int L, int R)
{
	msum[o] = lsum[o] = rsum[o] = R-L+1;
	cover[o] = -1;
	if(L == R) return ;
	int M = L + (R-L)/2;
	build(lc, L, M);
	build(rc, M+1, R);
}

void pushup(int o, int m)
{
	lsum[o] = lsum[lc];
	rsum[o] = rsum[rc];
	if(lsum[o] == m - (m>>1)) lsum[o] += lsum[rc];
	if(rsum[o] == (m>>1)) rsum[o] += rsum[lc];
	msum[o] = max(lsum[rc] + rsum[lc], max(msum[lc], msum[rc]));
}

void pushdown(int o, int m)
{
	if(cover[o] != -1)
	{
		cover[lc] = cover[rc] = cover[o];
		msum[lc] = lsum[lc] = rsum[lc] = cover[o]? 0: m-(m>>1);
		msum[rc] = lsum[rc] = rsum[rc] = cover[o]? 0: (m>>1);
		cover[o] = -1;
	}
}

void update(int o, int y1, int y2, int L, int R, int op)
{
	if(y1 <= L && y2 >= R)
	{
		msum[o] = lsum[o] = rsum[o] = op? 0: (R-L+1);
		cover[o] = op;
		return ;
	}
	pushdown(o, R-L+1);
	int M = L + (R-L)/2;
	if(y1 <= M) update(lc, y1, y2, L, M, op);
	if(y2 > M) update(rc, y1, y2, M+1, R, op);
	pushup(o, R-L+1);
}

int query(int o, int L, int R, int v)
{
	if(L == R) return L;
	pushdown(o, R-L+1);
	int M = L + (R-L)/2;
	if(msum[lc] >= v) return query(lc, L, M, v);
	else if(lsum[rc] + rsum[lc] >= v) return (M-rsum[lc]+1);
	return query(rc, M+1, R, v);
}

void solve()
{
	build(1, 1, n);
	int op, v;
	int y1, y2;
	while(m--)
	{
		scanf("%d", &op);
		if(op == 1)
		{
			scanf("%d", &v);
			if(msum[1] < v) { printf("0\n"); continue; }
			int p = query(1, 1, n, v);
			printf("%d\n", p);
			update(1, p, p+v-1, 1, n, 1);
		}
		else
		{
			scanf("%d%d", &y1, &y2);
			update(1, y1, y1+y2-1, 1, n, 0);
		}
	}
}

int main()
{
	while(~scanf("%d%d", &n, &m))
	{
		solve();
	}
	return 0;
}

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