Cod sursa(job #195849)

Utilizator Matei14Popa-Matei Mihai Matei14 Data 22 iunie 2008 10:45:17
Problema Hotel Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.37 kb
#include<stdio.h>
#include<string.h>
#define MAX 100007
struct tree{
	int li,ls;
	char v;
};
struct query{
	int key,lung;
};
int N,M,a,b;
tree arb[3*MAX];
query vec[MAX];
int poz[MAX],dimvec;
int limi,lims;
void inregistrare(int left,int right,int nod){
	int m=(left+right)>>1;
	arb[nod].li=left;
	arb[nod].ls=right;
	if (left==right)
		return;
	inregistrare(left,m,nod<<1);
	inregistrare(m+1,right,(nod<<1)+1);
}
int free(int left,int right,int nod){
	int m=(arb[nod].li+arb[nod].ls)>>1;
	if((left<=arb[nod].li)&&(arb[nod].ls<=right))
		return arb[nod].v;
	if(arb[nod].v!=1)
		return arb[nod].v;
	if(left<=m)
		if(right<=m)
			return free(left,right,nod<<1);
		else
			return free(left,right,nod<<1)+free(left,right,(nod<<1)+1);
	else
		return free(left,right,(nod<<1)+1);
}
int search_right(int left,int nod){
	int i,li=left,m,right=N+1;
	while (right-left>0){
		m=(right+left)>>1;
		if (free(left,m,1)==0)
			left=m+1;
		else
			right=m-1;
	}
	if (right+5<N)
		i=right+5;
	else
		i=N;
	while(i>=li){
		if(free(li,i,1)==0)
			return i;
		--i;
	}
	return li-1;
}
int search_left(int right,int nod){
	int i,ls=right,m,left=0;
	while(right-left>0){
		m=(right+left)>>1;
		if (free(m,right,1)==0)
			right=m-1;
		else
			left=m+1;
        }
	if (left-5<1)
		i=1;
	else
		i=left-5;
	while(i<=ls){
		if(free(i,ls,1)==0)
			return i;
		++i;
	}
	return ls+1;
}
void cazare(int left,int right,int nod){
	int m=(arb[nod].li+arb[nod].ls)>>1;
	if ((left<=arb[nod].li)&&(arb[nod].ls<=right)){
		arb[nod].v=2;
		return;
	}
	if (arb[nod].v==0){
		arb[nod<<1].v=0;arb[(nod<<1)+1].v=0;
	}
	if (left<=m)
		if (right<=m)
			cazare(left,right,nod<<1);
		else{
			cazare(left,right,nod<<1);
			cazare(left,right,(nod<<1)+1);
		}
	else
		cazare(left,right,(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 eliberare(int left,int right,int nod){
	int m=(arb[nod].li+arb[nod].ls)>>1;
	if ((left<=arb[nod].li)&&(arb[nod].ls<=right)){
		arb[nod].v=0;
		return;
	}
	if (arb[nod].v==2){
		arb[nod<<1].v=2;
		arb[(nod<<1)+1].v=2;
	}
	if (left<=m)
		if (right<=m)
			eliberare(left,right,nod<<1);
		else{
			eliberare(left,right,nod<<1);
			eliberare(left,right,(nod<<1)+1);
		}
	else
		eliberare(left,right,(nod<<1)+1);
	if((arb[nod<<1].v==0)&&(arb[(nod<<1)+1].v==0))
		arb[nod].v=0;
	else
		arb[nod].v=1;   
}
void go(int p){
	int fs,fd;
	query aux;
	while ((p<<1)<=dimvec){   
        fs=p<<1;
        if(fs<dimvec)
			fd=fs+1;
		else
			fd=fs;
		if(vec[fs].lung>vec[fd].lung)
			if (vec[fs].lung>vec[p].lung){
				aux=vec[fs];
				vec[fs]=vec[p];
				vec[p]=aux;
				poz[vec[fs].key]=fs;
				poz[vec[p].key]=p;
				p=fs;
			}
			else
				break;
			else
				if(vec[fd].lung>vec[p].lung){
					aux=vec[fd];
					vec[fd]=vec[p];
					vec[p]=aux;
					poz[vec[fd].key]=fd;
					poz[vec[p].key]=p;
					p=fd;
				}
				else
					break;
       }
}
void come(int p){
	int t;
	query aux;
	while (p>1){   
        t=p>>1;
        if (vec[t].lung<vec[p].lung){
            aux=vec[t];
            vec[t]=vec[p];
            vec[p]=aux;
            poz[vec[p].key]=p;
            poz[vec[t].key]=t;
            p=t;
		}
		else
			return;
	}
}
void vec_out(int p){
	int x;
	vec[p]=vec[dimvec--];
	x=vec[p].key;
	poz[x]=p;
	come(poz[x]);
	go(poz[x]);
}
void vec_in(int p,int lungime){
	int x;
	vec[++dimvec].key=p;
	vec[dimvec].lung=lungime;
	x=p;
	poz[x]=dimvec;
	come(poz[x]);   
}
int main(){
	int cod;
	freopen("hotel.in","r",stdin);
	freopen("hotel.out","w",stdout);
	scanf("%d %d",&N,&M);
	inregistrare(0,N+1,1);
	cazare(0,0,1);
	cazare(N+1,N+1,1);
	poz[1]=1;
	vec[dimvec=1].key=1;
	vec[1].lung=N;
	while(M){
		scanf("%d",&cod);
		if (cod==3)
			if (dimvec==0)
				printf("%d\n",0);
			else
				printf("%d\n",vec[1].lung);
		else{
			scanf("%d %d",&a,&b);
			b=a+b-1;
			if (cod==1){
				cazare(a,b,1);
				limi=search_left(a-1,1);
				lims=search_right(b+1,1);
				vec_out(poz[limi]);
				if (limi<a)
					vec_in(limi,a-limi);
				if (lims>b)
					vec_in(b+1,lims-b);
			}
			else{
				eliberare(a,b,1);
				limi=search_left(a-1,1);
				lims=search_right(b+1,1);
				if (limi<a)
					vec_out(poz[limi]);
				if (lims>b)
					vec_out(poz[b+1]);
				vec_in(limi,lims-limi+1);
			}
		}
	--M;
	}
	return 0;   
}