Cod sursa(job #726581)

Utilizator feelshiftFeelshift feelshift Data 27 martie 2012 12:36:44
Problema Hotel Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.74 kb
// http://infoarena.ro/problema/hotel
#include <fstream>
using namespace std;

#define leftSon 2*node
#define rightSon 2*node+1
#define begin first
#define end second
#define willBeAdded 1
#define willBeRemoved -1

const int MAXSIZE = 100001;

ifstream in("hotel.in");
ofstream out("hotel.out");

struct hareza { int left,value,right,willBeUpdated; };

int rooms,instructions,newValue;
pair<int,int> interval;
hareza tree[4*MAXSIZE];

void expand(int node,int left,int right);
void update(int node,int left,int right);

int main() {
	in >> rooms >> instructions;
	
	tree[1].willBeUpdated = willBeRemoved;
	expand(1,1,rooms);
	
	int type = 0,length;
	for(int i=1;i<=instructions;i++) {
		in >> type;
		
		switch(type) {
			case 1: {
				in >> interval.begin >> length;
				interval.end = interval.begin + length - 1;
				newValue = willBeAdded;
				update(1,1,rooms);
				break;
			};
			
			case 2: {
				in >> interval.begin >> length;
				interval.end = interval.begin + length - 1;
				newValue = willBeRemoved;
				update(1,1,rooms);
				break;
			};
			
			case 3: {
				out << tree[1].value << "\n";
			};
		}
	}

	return (0);
}

void expand(int node,int left,int right) {
	if(tree[node].willBeUpdated) {
		switch(tree[node].willBeUpdated) {
			case willBeAdded: { tree[node].value = tree[node].left = tree[node].right = 0; break; };
			case willBeRemoved: { tree[node].value = tree[node].left = tree[node].right = right - left + 1; break; };
		}
		
		if(left != right)
			tree[leftSon].willBeUpdated = tree[rightSon].willBeUpdated = tree[node].willBeUpdated;
		
		tree[node].willBeUpdated = 0;
	}
}

void update(int node,int left,int right) {
	if(interval.begin <= left && right <= interval.end) {
		tree[node].willBeUpdated = newValue;
		expand(node,left,right);
	}
	else {
		expand(node,left,right);
		
		int middle = (left + right) / 2;
		
		if(interval.begin <= middle)
			update(leftSon,left,middle);
		
		if(middle < interval.end)
			update(rightSon,middle+1,right);
		
		expand(leftSon,left,middle);
		expand(rightSon,middle+1,right);
		
		int leftSonLongestSubstring = tree[leftSon].value;
		int rightSonLongestSubstring = tree[rightSon].value;
		int longestSubstring = max(leftSonLongestSubstring,rightSonLongestSubstring);
		
		int reunionLength = tree[leftSon].right + tree[rightSon].left;
		
		tree[node].value = max(longestSubstring,reunionLength);
		
		if(tree[leftSon].value == middle - left + 1)
			tree[node].left = middle - left + 1 + tree[rightSon].left;
		else
			tree[node].left = tree[leftSon].left;
		
		if(tree[rightSon].value == right - middle)
			tree[node].right = right - middle + tree[leftSon].right;
		else
			tree[node].right = tree[rightSon].right;
	}
}