Cod sursa(job #2230710)

Utilizator DRLDRLRaul Ronald Galea DRLDRL Data 11 august 2018 01:18:53
Problema Hotel Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.4 kb
#pragma once

#include<fstream>
#include<iostream>

#define dim 400000

using namespace std;

/*
	nod.leftSeqMax = lungimea maxima de camere libere ce incepe din stanga intervalului
	nod.rightSeqMax = --||-- dreapta
	nod.seqMax = secventa maxima pe interval
*/

class Nod {
public:
	int seqMax, leftSeqMax, rightSeqMax;
public:
	Nod() {};
	Nod(int seqMax, int leftSeqMax, int rightSeqMax) {
		this->seqMax = seqMax;
		this->rightSeqMax = rightSeqMax;
		this->leftSeqMax = leftSeqMax;
	}

};


Nod arbintMAX[dim];
int lazy[dim];

// lazy 1 - interval should be freed, lazy 2 - interval should be occupied, lazy 0 - no pending update

void manageNode(int nod, int st, int dr) {
	if (lazy[nod] != 0) {
		if (lazy[nod] == 1) {
			arbintMAX[nod] = Nod(dr - st + 1, dr - st + 1, dr - st + 1);
		}
		if (lazy[nod] == 2) {
			arbintMAX[nod] = Nod(0,0,0);
		}
		if (st != dr) {
			lazy[2 * nod] = lazy[nod];
			lazy[2 * nod + 1] = lazy[nod]; // propagate
		}
		lazy[nod] = 0; // updated and propagated
	}
}

int max(int a, int b) {
	if (a > b)
		return a;
	return b;
}


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

	arbintMAX[nod] = Nod(dr - st + 1, dr - st + 1, dr-st + 1);

	if (st == dr) {
		return;
	}

	int mid = st + (dr - st) / 2;
	build(2 * nod, st, mid);
	build(2 * nod + 1, mid + 1, dr);


}
 


void update(int nod, int st, int dr, int uStart, int uEnd, int ocupat) { 
	manageNode(nod, st, dr);
	if (uStart <= st && uEnd >= dr) {
		if (ocupat == 1) { // se ocupa
			arbintMAX[nod] = Nod(0, 0, 0);
			lazy[2 * nod] = 2;
			lazy[2 * nod + 1] = 2;
		}
		else {
			arbintMAX[nod] = Nod(dr - st + 1, dr - st + 1, dr - st + 1);
			lazy[2 * nod] = 1;
			lazy[2 * nod + 1] = 1;
		}
		return;
	}
	int mid = st + (dr - st) / 2;
	if (uStart <= mid)
		update(2 * nod, st, mid, uStart, uEnd, ocupat);
	if (uEnd > mid)
		update(2 * nod + 1, mid + 1, dr, uStart, uEnd, ocupat);

	manageNode(2*nod, st, mid);
	manageNode(2*nod+1, mid+1, dr);

	// seqMax
	int longestStandalone = max(arbintMAX[2 * nod].seqMax, arbintMAX[2 * nod + 1].seqMax);
	int longestConnected = arbintMAX[2 * nod].rightSeqMax + arbintMAX[2 * nod + 1].leftSeqMax;
	arbintMAX[nod].seqMax = max(longestStandalone, longestConnected);

	// leftSeqMax
	if (arbintMAX[2 * nod].leftSeqMax == arbintMAX[2 * nod].seqMax && arbintMAX[2 * nod].seqMax == mid-st+1) {  // the interval is all emplty, the left starting longest of the right child will also contribute
		arbintMAX[nod].leftSeqMax = arbintMAX[2 * nod].leftSeqMax + arbintMAX[2 * nod + 1].leftSeqMax;
	}
	else { // intervals "disconnected"
		arbintMAX[nod].leftSeqMax = arbintMAX[2 * nod].leftSeqMax;
	}

	// rightSeqMax
	if (arbintMAX[2 * nod + 1].rightSeqMax == arbintMAX[2 * nod + 1].seqMax && arbintMAX[2 * nod + 1].seqMax == dr-mid) {
		arbintMAX[nod].rightSeqMax = arbintMAX[2 * nod + 1].rightSeqMax + arbintMAX[2 * nod].rightSeqMax;
	}
	else {
		arbintMAX[nod].rightSeqMax = arbintMAX[2 * nod + 1].rightSeqMax;
	}

	
}


int main() {

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


	int N, P, c, poz, nr;
	fin >> N >> P;
	build(1, 1, N);

	while (P) {
		fin >> c;
		if (c == 1) {
			fin >> poz >> nr;
			update(1, 1, N, poz, poz + nr - 1, 1);
		}
		if (c == 2) {
			fin >> poz >> nr;
			update(1, 1, N, poz, poz + nr - 1, 0);
		}
		if (c == 3) {
			fout << arbintMAX[1].seqMax<<"\n";
		}
		P--;
	}
	return 0;

}