Cod sursa(job #282256)

Utilizator CezarMocanCezar Mocan CezarMocan Data 17 martie 2009 10:45:17
Problema Hotel Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.57 kb
#include <cstdio>
#define maxn 100100

using namespace std;

struct arbore {
	int stg, dr, tot;
};

arbore v[5 * maxn];
int n, i, j, a, b, q, p;

void init(int nod, int left, int right) {
	int m = (left + right) / 2;
	v[nod].stg = v[nod].dr = v[nod].tot = right - left + 1;
	
	if (left != right) {
		init(2 * nod, left, m);
		init(2 * nod + 1, m + 1, right);
	}
}

inline int max(int a, int b) {
	if (a > b)
		return a;
	else
		return b;
}

void update1(int nod, int left, int right, int l1, int l2) {
	int m = (left + right) / 2;
	//la asta fac 1, adica zona libera se termina
	
	if (l1 <= left && right <= l2) {
		v[nod].stg = v[nod].dr = v[nod].tot = 0;
		return;
	}

	if (v[nod].tot == (right - left + 1)) {
		v[2 * nod].stg = v[2 * nod].dr = v[2 * nod].tot =  m - left + 1;
		v[2 * nod + 1].stg = v[2 * nod + 1].dr = v[2 * nod + 1].tot = right - m;	
	}

	if (l1 <= m) 
		update1(2 * nod, left, m, l1, l2);
	if (l2 > m)
		update1(2 * nod + 1, m + 1, right, l1, l2);

	if (v[2 * nod].stg == m - left + 1)
		v[nod].stg = v[2 * nod].stg + v[2 * nod + 1].stg;
	else
		v[nod].stg = v[2 * nod].stg;

	if (v[2 * nod + 1].dr == right - m)
		v[nod].dr = v[2 * nod + 1].dr + v[2 * nod].dr;
	else
		v[nod].dr = v[2 * nod + 1].dr;

	v[nod].tot = max(v[2 * nod].tot, v[2 * nod + 1].tot);
	v[nod].tot = max(v[nod].tot, v[2 * nod].dr + v[2 * nod + 1].stg);
}

void update2(int nod, int left, int right, int l1, int l2) {
	int m = (left + right) >> 1;
	int f1 = 2 * nod, f2 = 2 * nod + 1;

	//la asta fac 0, adica se elibereaza o zona
	
	
	if (l1 <= left && right <= l2) {
		v[nod].stg = v[nod].dr = v[nod].tot = right - left + 1;
		return;
	}

	if (v[nod].tot == 0) {
		v[f1].stg = v[f1].dr = v[f1].tot = 0;
		v[f2].stg = v[f2].dr = v[f2].tot = 0;	
	}

	if (l1 <= m) 
		update2(f1, left, m, l1, l2);
	if (l2 > m)
		update2(f2, m + 1, right, l1, l2);

	if (v[f1].stg == m - left + 1)
		v[nod].stg = v[f1].stg + v[f2].stg;
	else
		v[nod].stg = v[f1].stg;

	if (v[f2].dr == right - m)
		v[nod].dr = v[f2].dr + v[f1].dr;
	else
		v[nod].dr = v[f2].dr;

	v[nod].tot = max(v[f1].tot, v[f2].tot);
	v[nod].tot = max(v[nod].tot, v[f1].dr + v[f2].stg);

//	fprintf(stderr, "%d %d %d %d %d\n", left, right, l1, l2, v[nod].tot);
}

int main() {
	freopen("hotel.in", "r", stdin);
	freopen("hotel.out", "w", stdout);

	scanf("%d%d", &n, &p);
	
	init(1, 1, n);

	for (i = 1; i <= p; i++) {
		scanf("%d", &q);
		if (q == 3) 
			printf("%d\n", v[1].tot);

		if (q == 1) {
			scanf("%d%d", &a, &b);
			b = a + b - 1;
			update1(1, 1, n, a, b);
		}

		if (q == 2) {
			scanf("%d%d", &a, &b);
			b = a + b - 1;
			update2(1, 1, n, a, b);
		}
	}

	return 0;
}