Cod sursa(job #919626)

Utilizator ELHoriaHoria Cretescu ELHoria Data 19 martie 2013 19:15:31
Problema Hotel Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.88 kb
#include <fstream>
#include <algorithm>

using namespace std;

ifstream cin("hotel.in");
ofstream cout("hotel.out");
 
const int NMAX = int(1e5) + 2;
int N, P;

struct node { 
	int a, b, c;
	node() {
		a = b = c = 0;
	}
};

node arb[NMAX*4 + 10];

void buildTree(int v,int l,int r) {
	arb[v].a = arb[v].b = arb[v].c = r - l + 1;
	if(l == r) return;
	int mid = (l + r)>>1;
	buildTree(v<<1,l,mid);
	buildTree((v<<1) + 1,mid + 1,r);
}

void update1(int v,int Left,int Right,int lB,int rB);
void update2(int v,int Left,int Right,int lB,int rB);

inline void updateSons(int v,int l,int r) {
	int mid = (l + r)>>1;
	int leftSon = v<<1;
	int rightSon = leftSon + 1;
	if(arb[v].c == r - l + 1) {
		arb[leftSon].a = arb[leftSon].b = arb[leftSon].c = mid - l + 1;
		arb[rightSon].a = arb[rightSon].b = arb[rightSon].c = r - mid;
	}
	else
	if(arb[v].c == 0) {
		arb[leftSon].a = arb[leftSon].b = arb[leftSon].c = 0;
		arb[rightSon].a = arb[rightSon].b = arb[rightSon].c = 0;
	}
}

void update1(int v,int Left,int Right,int lB,int rB){ 
	if(Right < lB || Left > rB) return;
	updateSons(v,Left,Right);
	if(lB <= Left && Right <= rB) {
		arb[v].a = arb[v].b = arb[v].c = 0;
		return;
	}
	if(Left == Right) return;
	int mid = (Left + Right)>>1;
	int leftSon = v<<1;
	int rightSon = leftSon + 1;
	update1(leftSon,Left,mid,lB,rB);
	update1(rightSon,mid + 1,Right,lB,rB);
	arb[v].a = arb[leftSon].a;
	if(arb[leftSon].a == mid - Left + 1) {
		arb[v].a += arb[rightSon].a;
	}
	arb[v].b = arb[rightSon].b;
	if(arb[rightSon].b == Right - mid) {
		arb[v].b += arb[leftSon].b;
	}
	arb[v].c = arb[leftSon].b + arb[rightSon].a;
	arb[v].c = max(max(arb[v].c,arb[v].a),arb[v].b);
	arb[v].c = max(max(arb[v].c,arb[leftSon].c),arb[rightSon].c);

}

void update2(int v,int Left,int Right,int lB,int rB){ 
	if(Right < lB || Left > rB) return;
	updateSons(v,Left,Right);
	if(lB <= Left && Right <= rB) {
		arb[v].a = arb[v].b = arb[v].c = Right - Left + 1;
		return;
	}
	if(Left == Right) return;
	int leftSon = v<<1;
	int rightSon = leftSon + 1;
	int mid = (Left + Right)>>1;
	update2(leftSon,Left,mid,lB,rB);
	update2(rightSon,mid + 1,Right,lB,rB);
	arb[v].a = arb[leftSon].a;
	if(arb[leftSon].a == mid - Left + 1) {
		arb[v].a += arb[rightSon].a;
	}
	arb[v].b = arb[rightSon].b;
	if(arb[rightSon].b == Right - mid) {
		arb[v].b += arb[leftSon].b;
	}
	arb[v].c = arb[leftSon].b + arb[rightSon].a;
	arb[v].c = max(max(arb[v].c,arb[v].a),arb[v].b);
	arb[v].c = max(max(arb[v].c,arb[leftSon].c),arb[rightSon].c);
}


inline int query() {
	return arb[1].c;
}
 
int main() {
	
	cin>>N>>P;
	buildTree(1,1,N);
	
	for(int t, pos, num;P;P--) {
		cin>>t;
		if(t == 1) {
			cin>>pos>>num;
			update1(1,1,N,pos,pos + num - 1);
		} else
		if(t == 2) {
			cin>>pos>>num;
			update2(1,1,N,pos,pos + num - 1);
		} else {
			cout<<query()<<"\n";
		}
	}
	
    return 0;
}