Cod sursa(job #702461)

Utilizator okros_alexandruOkros Alexandru okros_alexandru Data 1 martie 2012 21:56:31
Problema Hotel Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.9 kb
#include <cstdio>
#define NMAx 200100
#define left_son(x) (2*x)
#define right_son(x) (2*x+1)
#define max(a,b) ((a)>(b)?(a):(b))
#define set(nod,val) (ARB[nod].left=ARB[nod].right=ARB[nod].info=val)
using namespace std;

struct ArbNod{int left,right,info;} ARB[2*NMAx];
int n,T,A,B,M;

void Build(int nod,int left,int right) {
	
	set(nod,right-left+1);
	
	if(left==right)
		return;
	
	int mid=(left+right)>>1;
	
	Build(left_son(nod),left,mid);
	Build(right_son(nod),mid+1,right);
	
}
ArbNod Unite(int nod,int left,int right) {
	
	ArbNod Sol;
	int mid=(left+right)>>1;
	
	Sol.left=ARB[left_son(nod)].left;
	if(ARB[left_son(nod)].left==mid-left+1)
		Sol.left+=ARB[right_son(nod)].left;

	Sol.right=ARB[right_son(nod)].right;
	if(ARB[right_son(nod)].right==right-mid)
		Sol.right+=ARB[left_son(nod)].right;
		
	Sol.info=max(ARB[left_son(nod)].info,ARB[right_son(nod)].info);
	
	Sol.info=max(Sol.info,ARB[left_son(nod)].right+ARB[right_son(nod)].left);
	
	return Sol;
	
}
void Update(int nod,int left,int right,int VAL) {
	
	if(A<=left&&right<=B) {
		if(VAL==1)
			set(nod,0);
		else
			set(nod,right-left+1);
		return;
		}
	
	if(left==right)
		return;
	
	int mid=(left+right)>>1;
	
	if(ARB[nod].info==right-left+1) {
		set(left_son(nod),mid-left+1);
		set(right_son(nod),right-mid);
		}
	else
	if(ARB[nod].info==0) {
		set(left_son(nod),0);
		set(right_son(nod),0);
		}
	
	if(A<=mid)
		Update(left_son(nod),left,mid,VAL);
	if(B>=mid+1)
		Update(right_son(nod),mid+1,right,VAL);
	
	ARB[nod]=Unite(nod,left,right);
	
}
int main() {
	
	int i,cod;
	freopen("hotel.in","r",stdin);
	freopen("hotel.out","w",stdout);
	
	scanf("%d %d",&n,&T);
	Build(1,1,n);
	
	for(i=1;i<=T;i++) {
		
		scanf("%d",&cod);
		
		if(cod==3)
			printf("%d\n",ARB[1].info);
		else {
			scanf("%d %d",&A,&B);
			
			B+=A-1;
			Update(1,1,n,cod);
				
			}
		}
	
	return 0;
	
}