Cod sursa(job #612194)

Utilizator CBogdanCiobanu Bogdan CBogdan Data 6 septembrie 2011 14:03:04
Problema Hotel Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.9 kb
#include<cstdio>
using namespace std;

int n,k,i,a,b,type,val[300010],RIGHT[300010],LEFT[300010],deprop[300010];

void read(),solve(),init(int,int,int),come(int,int,int,int,int),leave(int,int,int,int,int),propagate(int,int,int);
/*
struct tree
{
	int val;
	int left;
	int right;
	int deprop;
} arb[300010];*/

int main()
{
	read();
	solve();
	
	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(i=1;i<=k;i++)
	{
		scanf("%d",&type);
		if(type==3)printf("%d\n",val[1]);
		else if(type==2)
		{
			scanf("%d%d",&a,&b);
			b+=a-1;
			leave(1,1,n,a,b);
		}
		else if(type==1)
		{
			scanf("%d%d",&a,&b);
			b+=a-1;
			come(1,1,n,a,b);
		}
	}
}

void init(int nod, int left,int right)
{
	val[nod]=right-left+1;
	LEFT[nod]=right-left+1;
	RIGHT[nod]=right-left+1;
	deprop[nod]=0;
	if(left==right)return;
	
	int mid=(left+right)/2;
	
	init(2*nod,left,mid);
	init(2*nod+1,mid+1,right);
}

void leave(int nod,int left,int right,int a,int b)
{
	if(deprop[nod]!=0)propagate(nod,left,right);
	if(a<=left && right<=b)
	{
		val[nod]=right-left+1;
		LEFT[nod]=right-left+1;
		RIGHT[nod]=right-left+1;
		deprop[nod]=-1;
		return;
	}
	//if(left==right)return;
	
	int mid=(left+right)/2;
	
	if(a<=mid)leave(nod*2,left,mid,a,b);
	if(mid<b) leave(nod*2+1,mid+1,right,a,b);
	
	val[nod]=val[nod*2]>val[nod*2+1]?val[nod*2]:val[nod*2+1];
	
	if(val[nod]<RIGHT[nod*2]+LEFT[nod*2+1])val[nod]=RIGHT[nod*2]+LEFT[nod*2+1];
	
	LEFT[nod]=LEFT[nod*2];
	if(LEFT[nod]==mid-left+1) LEFT[nod]+=LEFT[nod*2+1];
	
	RIGHT[nod]=RIGHT[nod*2+1];
	if(RIGHT[nod]==right-mid) RIGHT[nod]+=RIGHT[nod*2];
}

void come(int nod,int left,int right,int a,int b)
{
	if(deprop[nod]!=0)propagate(nod,left,right);
	if(a<=left && right<=b)
	{
		val[nod]=0;
		LEFT[nod]=0;
		RIGHT[nod]=0;
		deprop[nod]=1;
		return;
	}
	//if(left==right)return;
	
	int mid=(left+right)/2;
	
	if(a<=mid)come(nod*2,left,mid,a,b);
	if(mid<b) come(nod*2+1,mid+1,right,a,b);
	
	val[nod]=val[nod*2]>val[nod*2+1]?val[nod*2]:val[nod*2+1];
	if(val[nod]<RIGHT[nod*2]+LEFT[nod*2+1])val[nod]=RIGHT[nod*2]+LEFT[nod*2+1];
	
	LEFT[nod]=LEFT[nod*2];
	if(LEFT[nod]==mid-left+1) LEFT[nod]+=LEFT[nod*2+1];
	
	RIGHT[nod]=RIGHT[nod*2+1];
	if(RIGHT[nod]==right-mid) RIGHT[nod]+=RIGHT[nod*2];
}

void propagate(int nod,int left,int right)
{
	if(left==right){deprop[nod]=0;return;}
	int mid=(left+right)/2;
	if(deprop[nod]==1)
	{
		val[nod*2]=0;
		LEFT[nod*2]=0;
		RIGHT[nod*2]=0;
		deprop[nod*2]=1;
		
		val[nod*2+1]=0;
		LEFT[nod*2+1]=0;
		RIGHT[nod*2+1]=0;
		deprop[nod*2+1]=1;
	}
	else
	{
		val[nod*2]=mid-left+1;
		LEFT[nod*2]=mid-left+1;
		RIGHT[nod*2]=mid-left+1;
		deprop[nod*2]=-1;
		
		val[nod*2+1]=right-mid;
		LEFT[nod*2+1]=right-mid;
		RIGHT[nod*2+1]=right-mid;
		deprop[nod*2+1]=-1;
		
	}
	deprop[nod]=0;
}