Cod sursa(job #595445)

Utilizator maritimCristian Lambru maritim Data 12 iunie 2011 17:52:44
Problema Hotel Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.84 kb
#include<stdio.h>
#include<vector.h>

#define MaxN 1000100
#define sum dr - st + 1
#define lf (2 * nod)
#define rf (2 * nod) + 1
#define mij (st + dr) / 2

int AIC[MaxN];
int AIL[MaxN];
int AIR[MaxN];
short int UPD[MaxN];
int N;
int P;
int stare;
int a;
int b;

int max(int a,int b)
{
	return a>b ? a:b;
}

void build(int nod,int st,int dr)
{
	AIC[nod] = sum;
	AIL[nod] = sum;
	AIR[nod] = sum;
	if(st < dr)
	{
		build(lf , st , mij);
		build(rf , mij + 1 , dr);
	}
}

int update(int nod,int st,int dr,int a,int b,int v)
{
	// daca intervalul st - dr face parte din a - b il updatam cu totul
	if(a <= st && b >= dr)
	{
		UPD[nod] = v;
		
		AIC[nod] = v*(sum);
		AIL[nod] = v*(sum);
		AIR[nod] = v*(sum);
		return 0;
	}
	
	// daca s-a updatat anterior intervalul prezent , fara
	// updatarea intervalului inferior se updateaza un nivel
	if(UPD[nod] != -1)
	{
		update(lf , st , mij , st , mij , UPD[nod]);
		update(rf , mij + 1 , dr , mij + 1 , dr , UPD[nod]);
		UPD[nod] = -1;
	}
	
	// se updateaza stanga
	if(a <= mij)
		update(lf , st , mij , a , b , v);
	// se updateaza dreapta
	if(b > mij)
		update(rf , mij + 1 , dr , a , b , v);
	
	// se updateaza fiecare interval din nod
	AIC[nod] = max(max(AIC[lf] , AIC[rf]) , AIR[lf] + AIL[rf]);
	if(AIR[rf] == dr - mij)
		AIR[nod] = AIR[lf] + AIR[rf];
	else
		AIR[nod] = AIR[rf];
	if(AIL[lf] == mij - st + 1)
		AIL[nod] = AIL[lf] + AIL[rf];
	else
		AIL[nod] = AIL[lf];
}

int main()
{
	FILE *f = fopen("hotel.in","r");
	FILE *g = fopen("hotel.out","w");
	
	fscanf(f,"%d %d",&N,&P);
	build(1,1,N);
	memset(UPD , -1 , sizeof(UPD));
	for(int i=1;i<=P;i++)
	{
		fscanf(f,"%d ",&stare);
		if(stare < 3)
		{
			fscanf(f,"%d %d",&a,&b);
			update(1,1,N,a,a+b-1,1-stare%2);
		}
		else
			fprintf(g,"%d\n",AIC[1]);
	}
	
	fclose(g);
	fclose(f);
}