Cod sursa(job #82200)

Utilizator flionIonescu Ionut Florin flion Data 5 septembrie 2007 21:46:23
Problema Hotel Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.05 kb
#include <stdio.h>

#define NMAX 32000

int MAX[NMAX], STG[NMAX], DRE[NMAX], NEGRU[NMAX];

int N, Q, i, t, a, b;

void populate(int nod, int st, int dr)
{
	if (st == dr)
	{
		MAX[nod] = STG[nod] = DRE[nod] = 1;
	}
	else
	{
		int m = (st+dr)>>1;

		populate(nod<<1, st, m);

		populate(nod<<1|1, m+1, dr);

		MAX[nod] = STG[nod] = DRE[nod] = dr-st+1;
	}
}



void insert(int nod, int st, int dr, int a, int b)
{
	if (a <= st && dr <= b)
	{
		NEGRU[nod] = 1;

		MAX[nod] = STG[nod] = DRE[nod] = 0;
	}
	else
	{
		int m = (st+dr)>>1;

		if (a <= m)
			insert(nod<<1, st, m, a, b);

		if (b > m)
			insert(nod<<1|1, m+1, dr, a, b);

		STG[nod] = STG[nod<<1];
		if (STG[nod<<1] == m-st+1)
			STG[nod] += STG[nod<<1|1];

		DRE[nod] = DRE[nod<<1|1];
		if (DRE[nod<<1|1] == dr-m)
			DRE[nod] += DRE[nod<<1];

		MAX[nod] = MAX[nod<<1] > MAX[nod<<1|1]? MAX[nod<<1]: MAX[nod<<1|1];

		MAX[nod] = STG[nod] > MAX[nod]? STG[nod]: MAX[nod];

		MAX[nod] = DRE[nod] > MAX[nod]? DRE[nod]: MAX[nod];

		if (DRE[nod<<1]+STG[nod<<1|1] > MAX[nod])
			MAX[nod] = DRE[nod<<1]+STG[nod<<1|1];

		if (MAX[nod] == 0)
			NEGRU[nod] = 1;
	}
}

void remove(int nod, int st, int dr, int a, int b, int mostenire)
{
	if (mostenire == 1)
	{
		NEGRU[nod] = 1;
		MAX[nod] = STG[nod] = DRE[nod] = 0;
	}

	int m = (st+dr)>>1;

	if (a <= st && dr <= b)
	{
		NEGRU[nod<<1] = NEGRU[nod<<1|1] = 0;

		MAX[nod<<1] = STG[nod<<1] = DRE[nod<<1] = m-st+1;
		MAX[nod<<1|1] = STG[nod<<1|1] = DRE[nod<<1|1] = dr-m;

		NEGRU[nod] = 0;
		MAX[nod] = STG[nod] = DRE[nod] = dr-st+1;
	}
	else
	{
		// incearca la stanga
		int r0 = 0, r1 = 0;

		if (a <= m)
		{
			r0 = 1;
			remove(nod<<1, st, m, a, b, NEGRU[nod]);
		}

		if (m < b)
		{
			r1 = 1;
			remove(nod<<1|1, m+1, dr, a, b, NEGRU[nod]);
		}

		// era nod negru
		if (NEGRU[nod] == 1)
		{
			// am mers in ambele rezultate, ambele sunt 0
			if (r0 == 1 && r1 == 1)
			{
				STG[nod] = STG[nod<<1];
				if (STG[nod<<1] == m-st+1)
					STG[nod] += STG[nod<<1|1];

				DRE[nod] = DRE[nod<<1|1];
				if (DRE[nod<<1|1] == dr-m)
					DRE[nod] += DRE[nod<<1];

				MAX[nod] = MAX[nod<<1] > MAX[nod<<1|1]? MAX[nod<<1]: MAX[nod<<1|1];

				MAX[nod] = STG[nod] > MAX[nod]? STG[nod]: MAX[nod];

				MAX[nod] = DRE[nod] > MAX[nod]? DRE[nod]: MAX[nod];

				if (DRE[nod<<1]+STG[nod<<1|1] > MAX[nod])
					MAX[nod] = DRE[nod<<1]+STG[nod<<1|1];

				NEGRU[nod] = 0;
			}
			else if (r0 == 1)
			{
				// am mers doar in partea stanga, fac partea dreapta neagra!
				NEGRU[nod<<1|1] = 1;
				MAX[nod<<1|1] = STG[nod<<1|1] = DRE[nod<<1|1] = 0;

				STG[nod] = STG[nod<<1];

				DRE[nod] = 0;

				MAX[nod] = MAX[nod<<1];

				NEGRU[nod] = 0;
			}
			else
			{
				// am mers doar in partea dreapta, fac partea stanga neagra!
				NEGRU[nod<<1] = 1;
				MAX[nod<<1] = STG[nod<<1] = DRE[nod<<1] = 0;

				STG[nod] = 0;

				DRE[nod] = DRE[nod<<1|1];

				MAX[nod] = MAX[nod<<1|1];

				NEGRU[nod] = 0;
			}
		}
		else
		{
		    // era nod normal

		    STG[nod] = STG[nod<<1];
		    if (STG[nod<<1] == m-st+1)
			STG[nod] += STG[nod<<1|1];

		    DRE[nod] = DRE[nod<<1|1];
		    if (DRE[nod<<1|1] == dr-m)
			DRE[nod] += DRE[nod<<1];

		    MAX[nod] = MAX[nod<<1] > MAX[nod<<1|1]? MAX[nod<<1]: MAX[nod<<1|1];

		    MAX[nod] = STG[nod] > MAX[nod]? STG[nod]: MAX[nod];

		    MAX[nod] = DRE[nod] > MAX[nod]? DRE[nod]: MAX[nod];

		    if (DRE[nod<<1]+STG[nod<<1|1] > MAX[nod])
			MAX[nod] = DRE[nod<<1]+STG[nod<<1|1];

		    NEGRU[nod] = 0; // ca sa ajung aici!
		}
	}
}

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

	scanf("%d%d", &N, &Q);

	populate(1, 1, N);



	for (i = 1; i <= Q; ++i)
	{
		scanf("%d", &t);

		switch(t)
		{
			case 1:
			{
				scanf("%d%d", &a, &b);
				insert(1, 1, N, a, a+b-1);
				break;
			}
			case 2:
			{
				scanf("%d%d", &a, &b);
				remove(1, 1, N, a, a+b-1, NEGRU[1]);
				break;
			}
			default:
			{
				printf("%d\n", MAX[1]);
				break;
			}
		}
	}

	return 0;
}