Cod sursa(job #69702)

Utilizator flionIonescu Ionut Florin flion Data 3 iulie 2007 23:00:25
Problema Hotel Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.24 kb
#include <stdio.h>

#define nmax 300000

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

int max[nmax], stg[nmax], dre[nmax], con[nmax];

void init(int nod, int s, int d)
{
	max[nod] = stg[nod] = dre[nod] = d-s+1;

	int m = (s + d) >> 1;

	if (m == d) // un singur element
		return;

	init(nod << 1, s, m);

	init(1 + (nod << 1), m+1, d);
}

void scoate (int nod, int s, int d, int a, int b)
{
	if (con[nod >> 1] == 1)
		con[nod] = 1;

	if (a <= s && d <= b)
	{
		stg[nod] = dre[nod] = max[nod] = d-s+1;
		con[nod] = 0;
	}

	else
	{
		int m = (s+d) >> 1;

		int stanga = 0, dreapta = 0;

		if (a <= m)
		{
			scoate (nod << 1, s, m, a, b);
			stanga = 1;
		}

		if (b > m)
		{
			scoate (1+(nod << 1), m+1, d, a, b);
			dreapta = 1;
		}

		// calculez stg(s, d)

		if (con[nod] == 0)
		{
		  stg[nod] = stg[nod << 1];
		  if (stg[nod] == m-s+1)
			stg[nod] += stg[1 + (nod << 1)];

		// calculez dre(s, d)
		  dre[nod] = dre[1 + (nod << 1)];
		  if (dre[nod] == d-m)
			dre[nod] += dre[nod << 1];

		  max[nod] = 0;

		  if (stg[nod] > max[nod])
			max[nod] = stg[nod];

		  if (dre[nod] > max[nod])
			max[nod] = dre[nod];

		  if (max[nod << 1] > max[nod])
			max[nod] = max[nod << 1];

		  if (max[(nod<<1)+1] > max[nod])
			max[nod] = max[(nod << 1) + 1];

		  if (dre[nod << 1] + stg[1+(nod<<1)] > max[nod])
			max[nod] = dre[nod << 1] + stg[1+(nod<<1)];
		}
		else
		{
		  con[nod] = 0;

		  if (stanga && dreapta) // amundoua
		  {
		    stg[nod] = dre[nod] = 0;
		    max[nod] = dre[nod << 1] + stg[1 + (nod << 1)];
		  }
		  else if (stanga) // doar stanga
		  {
		    max[nod] = stg[nod] = stg[nod << 1];
		    dre[nod] = 0;
		  }
		  else // doar dreapta
		  {
		    max[nod] = dre[nod] = dre[1 + (nod << 1)];
		    stg[nod] = 0;
		  }
		}
	}
}


void adauga (int nod, int s, int d, int a, int b)
{
	if (a <= s && d <= b)
	{
		stg[nod] = dre[nod] = max[nod] = 0;
		con[nod] = 1;
	}

	else
	{
		int m = (s+d) >> 1;

		if (a <= m)
			adauga (nod << 1, s, m, a, b);

		if (b > m)
			adauga (1+(nod << 1), m+1, d, a, b);

		// calculez stg(s, d)
		stg[nod] = stg[nod << 1];
		if (stg[nod] == m-s+1)
			stg[nod] += stg[1 + (nod << 1)];

		// calculez dre(s, d)
		dre[nod] = dre[1 + (nod << 1)];
		if (dre[nod] == d-m)
			dre[nod] += dre[nod << 1];

		max[nod] = 0;

		if (stg[nod] > max[nod])
			max[nod] = stg[nod];

		if (dre[nod] > max[nod])
			max[nod] = dre[nod];

		if (max[nod << 1] > max[nod])
			max[nod] = max[nod << 1];

		if (max[(nod<<1)+1] > max[nod])
			max[nod] = max[(nod << 1) + 1];

		if (dre[nod << 1] + stg[1+(nod<<1)] > max[nod])
			max[nod] = dre[nod << 1] + stg[1+(nod<<1)];

		max[nod] = max[nod];
	}
}

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

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

	init(1, 1, N);

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

	  switch(t)
	  {
	    case 1:
	    {
	      scanf("%d%d", &a, &b);
	      adauga(1, 1, N, a, a+b-1);

	      break;
	    }
	    case 2:
	    {
	      scanf("%d%d", &a, &b);
	      scoate(1, 1, N, a, a+b-1);

	      break;
	    }
	    default:
	    {
	      printf("%d\n", max[1]);
	    }
	  }
	}

	return 0;
}