Cod sursa(job #611554)

Utilizator CBogdanCiobanu Bogdan CBogdan Data 1 septembrie 2011 22:07:20
Problema Hotel Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.25 kb
#include<cstdio>
#include<ctime>
using namespace std;

double start,stop;
int n,k,i,a,b,st,dr,c,lg_curr[300010],lg_left[300010],lg_right[300010];

void read(),solve(),vin(int,int,int),pleaca(int,int,int),init(int,int,int);

int main()
{
	//start=clock();
	read();
	solve();
	//stop=clock();
	//printf("\n\n\n%lf", (stop-start)/CLOCKS_PER_SEC);
	
	return 0;
}

void read()
{
	freopen("hotel.in","r",stdin);
	freopen("hotel.out","w",stdout);
	scanf("%d%d",&n,&k);
}

void solve()
{
	init(1,1,n);
	for(;k--;)
	{
		scanf("%d",&c);
		if(c==3)
		{
			printf("%d\n",lg_curr[1]);
			continue;
		}
		scanf("%d%d",&a,&b);b+=a-1;
		if(c==1){vin(1,1,n);continue;}
		if(c==2){pleaca(1,1,n);continue;}
	}
}

void vin(int nod,int st,int dr)
{
	if(dr<a||st>b)return;
	if(a<=st&&dr<=b&&st==dr)
	{
		lg_curr[nod]=0;
		lg_left[nod]=0;
		lg_right[nod]=0;
		return;
	}
	if(st==dr)return;
	
	int mid=(st+dr)/2;
	if(a<=mid)vin(nod*2,st,mid);
	if(mid<b)vin(nod*2+1,mid+1,dr);
	
	lg_curr[nod]=lg_curr[nod*2]>lg_curr[nod*2+1]?lg_curr[nod*2]:lg_curr[nod*2];
	if(lg_right[nod*2]+lg_left[nod*2+1]>lg_curr[nod])
		lg_curr[nod]=lg_right[nod*2]+lg_left[nod*2+1];
	
	lg_left[nod]=lg_left[nod*2];
	if(lg_left[nod]==mid-st+1)
		lg_left[nod]+=lg_left[nod*2+1];
	
	lg_right[nod]=lg_right[nod*2+1];
	if(lg_right[nod]==dr-mid)
		lg_right[nod]+=lg_right[nod*2];
}

void pleaca(int nod, int st, int dr)
{

	if(dr<a||st>b)return;
	if(a<=st&&dr<=b&&st==dr)
	{
		lg_curr[nod]=dr-st+1;
		lg_left[nod]=dr-st+1;
		lg_right[nod]=dr-st+1;
		return;
	}
	if(st==dr)return;
	
	int mid=(st+dr)/2;
	
	if(a<=mid)pleaca(nod*2,st,mid);
	if(mid<b)pleaca(nod*2+1,mid+1,dr);
	
	lg_curr[nod]=lg_curr[nod*2]>lg_curr[nod*2+1]?lg_curr[nod*2]:lg_curr[nod*2];
	if(lg_right[nod*2]+lg_left[nod*2+1]>lg_curr[nod])
		lg_curr[nod]=lg_right[nod*2]+lg_left[nod*2+1];
	
	lg_left[nod]=lg_left[nod*2];
	if(lg_left[nod]==mid-st+1)
		lg_left[nod]+=lg_left[nod*2+1];
	
	lg_right[nod]=lg_right[nod*2+1];
	if(lg_right[nod]==dr-mid)
		lg_right[nod]+=lg_right[nod*2];
}

void init(int nod, int st, int dr)
{
	lg_curr[nod]=dr-st+1;
	lg_left[nod]=dr-st+1;
	lg_right[nod]=dr-st+1;
	if(st==dr)return;
	
	int mid= (st+dr)/2;
	
	init(nod*2,st,mid);
	init(nod*2+1,mid+1,dr);
}