Cod sursa(job #70558)

Utilizator flionIonescu Ionut Florin flion Data 6 iulie 2007 13:41:31
Problema Hotel Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.4 kb
#include <stdio.h>

#define nmax 1000001

int STG[nmax], DRE[nmax], MAX[nmax], PLI[nmax];

int M, N;

void fa (int nod, int s, int d)
{
	STG[nod] = DRE[nod] = MAX[nod] = d-s+1;

	if (s == d)
		return;

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

	fa(nod<<1, s, m);
	fa((nod<<1)+1, m+1, d);
}

void baga(int nod, int s, int d, int a, int b)
{
  if (a <= s && d <= b)
  {
    // modifica structura nodului curent
    // il fac plin

    PLI[nod] = 1;

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

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

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

    if (PLI[nod<<1] && PLI[1+(nod<<1)])
    {
	PLI[nod] = 1;
	MAX[nod] = STG[nod] = DRE[nod] = 0;
    }
    else
    {
      // nodul nu poate fi total ocupat...

      STG[nod] = MAX[nod] = DRE[nod] = 0;


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

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


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

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


      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[1+(nod<<1)] >= MAX[nod])
	MAX[nod] = MAX[1+(nod<<1)];

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

      MAX[nod] = MAX[nod];
    }
  }
}

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

  if (a <= s && d <= b)
  {
    // modific structura nodului curent

    STG[nod] = DRE[nod] = MAX[nod] = d-s+1;
    PLI[nod] = 0;
  }
  else
  {
    int m = (s+d)>>1;
    int l, r;
    r = l = 0;

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

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

    if (PLI[nod] == 1 && !(l && r))
    {
      if (l == 0)
      {
	PLI[nod<<1] = 1;
	MAX[nod<<1] = STG[nod<<1] = DRE[nod<<1] = 0;
      }
      if (r == 0)
      {
	PLI[1+(nod<<1)] = 1;
	MAX[1+(nod<<1)] = STG[1+(nod<<1)] = DRE[1+(nod<<1)] = 0;
      }
    }

    STG[nod] = MAX[nod] = DRE[nod] = 0;


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

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


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

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


    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[1+(nod<<1)] >= MAX[nod])
	MAX[nod] = MAX[1+(nod<<1)];

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


    PLI[nod] = 0;
  }
}

int main()
{
	int t, c, a, b;

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

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

	fa(1, 1, N);

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

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

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

	      break;
	    }
	    case 3:
	    {
	      printf("%d\n", MAX[1]);
	      break;
	    }
	  }
	}

	return 0;
}