Cod sursa(job #93974)

Utilizator vrajalaMihai Viteazu, razboinicu luminii vrajala Data 21 octombrie 2007 01:06:34
Problema Hotel Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 5.3 kb
#include <stdio.h>

#define Nmax 100005

struct arbore { int li,ls; char v; };
struct maxheap { int key,lung; };

int N,P,a,b;
arbore arb[3*Nmax+10];
maxheap heap[Nmax];
int poz[Nmax],dimheap;
int limi,lims; //limita inferioara respectiv superioara de ocupare care contine [a,b]

//BINARY SEARCH TREE

void etichetare(int st,int dr,int nod)
{
 int m=(st+dr)>>1;
 arb[nod].li=st;
 arb[nod].ls=dr;
 if (st==dr) return;
 etichetare(st,m,nod<<1);
 etichetare(m+1,dr,(nod<<1)+1);
}

int liber(int st,int dr,int nod)
{
 int m=(arb[nod].li+arb[nod].ls)>>1;
 if ((st<=arb[nod].li)&&(arb[nod].ls<=dr))
   return arb[nod].v;
 if (arb[nod].v!=1) return arb[nod].v;
 if (st<=m)
   if (dr<=m) return liber(st,dr,nod<<1);
   	else return liber(st,dr,nod<<1)+liber(st,dr,(nod<<1)+1);
   else return liber(st,dr,(nod<<1)+1);
}

int cauta_dreapta(int st,int nod)
{
 int m,dr=N+1;
 while (dr-st>0)
   	{
         m=(dr+st)>>1;
         if (liber(st,m,1)==0) st=m+1;
         	else dr=m-1;
        }
 if (liber(st,dr+1,1)==0) return dr+1;
 	else return dr;
/* int i;
 for (i=N;i>=st;--i)
     if (liber(st,i,1)==0) return i;
 return st-1;*/
}

int cauta_stanga(int dr,int nod)
{
 int m,st=0;
 while (dr-st>0)
   	{
         m=(dr+st)>>1;
         if (liber(m,dr,1)==0) dr=m-1;
         	else st=m+1;
        }
 if (liber(st,dr,1)==0) return st;
 	else return st+1;
/* int i;
 for (i=1;i<=dr;++i)
     if (liber(i,dr,1)==0) return i;
 return dr+1;*/
}

void cazare(int st,int dr,int nod)
{
 int m=(arb[nod].li+arb[nod].ls)>>1;
 if ((st<=arb[nod].li)&&(arb[nod].ls<=dr))
    {
     arb[nod].v=2;
     return;
    }
 if (arb[nod].v==0) { arb[nod<<1].v=0;arb[(nod<<1)+1].v=0; }
 if (st<=m)
    if (dr<=m) cazare(st,dr,nod<<1);
       else {
             cazare(st,dr,nod<<1);
             cazare(st,dr,(nod<<1)+1);
            }
    else cazare(st,dr,(nod<<1)+1);
 if ((arb[nod<<1].v==2)&&(arb[(nod<<1)+1].v==2)) arb[nod].v=2;
    else arb[nod].v=1;
}

void evacuare(int st,int dr,int nod)
{
 int m=(arb[nod].li+arb[nod].ls)>>1;
 if ((st<=arb[nod].li)&&(arb[nod].ls<=dr))
    {
     arb[nod].v=0;
    // if (nod&1) if (arb[nod>>1].v==2) arb[nod-1].v=2;
    //    else if (arb[nod>>1].v==2) arb[nod+1].v=2;
     return;
    }
 if (arb[nod].v==2)
    {
     arb[nod<<1].v=2;
     arb[(nod<<1)+1].v=2;
    }
 if (st<=m)
    if (dr<=m) evacuare(st,dr,nod<<1);
       else {
             evacuare(st,dr,nod<<1);
             evacuare(st,dr,(nod<<1)+1);
            }
    else evacuare(st,dr,(nod<<1)+1);
 if ((arb[nod<<1].v==0)&&(arb[(nod<<1)+1].v==0)) arb[nod].v=0;
     else arb[nod].v=1;
}

//MAX-HEAP

void go_down(int p)
{
 int fs,fd;
 maxheap aux;
 while ((p<<1)<dimheap)
       {
        fs=p<<1;
        if (fs<dimheap) fd=fs+1;
           else fd=fs;
        if (heap[fs].lung>heap[fd].lung)
           if (heap[fs].lung>heap[p].lung)
              {
               aux=heap[fs];
               heap[fs]=heap[p];
               heap[p]=aux;
               poz[heap[fs].key]=fs;
               poz[heap[p].key]=p;
               p=fs;
              }
           else break;
         else if (heap[fd].lung>heap[p].lung)
              {
               aux=heap[fd];
               heap[fd]=heap[p];
               heap[p]=aux;
               poz[heap[fd].key]=fd;
               poz[heap[p].key]=p;
               p=fd;
              }
          else break;
       }
}

void come_up(int p)
{
 int t;
 maxheap aux;
 while (p>1)
       {
        t=p>>1;
        if (heap[t].lung<heap[p].lung)
           {
            aux=heap[t];
            heap[t]=heap[p];
            heap[p]=aux;
            poz[heap[p].key]=p;
            poz[heap[t].key]=t;
            p=t;
           }
         else return;
       }
}

void heap_out(int p)
{
 int who;
 heap[p]=heap[dimheap--];
 who=heap[p].key;
 poz[who]=p;
 come_up(poz[who]);
 go_down(poz[who]);
}

void heap_in(int p,int lungime)
{
 int who;
 heap[++dimheap].key=p;
 heap[dimheap].lung=lungime;
 who=p;
 poz[who]=dimheap;
 come_up(poz[who]);
}

//MAIN

int main()
{
 int cod;
 freopen("hotel.in","r",stdin);
 freopen("hotel.out","w",stdout);
 scanf("%d %d",&N,&P);
 etichetare(0,N+1,1);
 cazare(0,0,1);
 cazare(N+1,N+1,1);
 poz[1]=1;
 heap[dimheap=1].key=1;
 heap[1].lung=N;
 while (P)
       {
        scanf("%d",&cod);
        if (cod==3) if (dimheap==0) printf("%d\n",0);
        	else printf("%d\n",heap[1].lung);
           else
               {
                scanf("%d %d",&a,&b);
                b=a+b-1;
                if (cod==1)
                   {
                    cazare(a,b,1);
                    limi=cauta_stanga(a-1,1);
                    lims=cauta_dreapta(b+1,1);
                    heap_out(poz[limi]);
                    if (limi!=a) heap_in(limi,a-limi);
                    if (lims!=b) heap_in(b+1,lims-b);
                   }
                   else
                   {
                    evacuare(a,b,1);
                    limi=cauta_stanga(a-1,1);
                    lims=cauta_dreapta(b+1,1);
                    if (limi<a) heap_out(poz[limi]);
                    if (lims>b) heap_out(poz[b+1]);
                    heap_in(limi,lims-limi+1);
                   }
               }
       --P;
       }
 return 0;
}