Cod sursa(job #532867)

Utilizator feelshiftFeelshift feelshift Data 12 februarie 2011 17:39:16
Problema Arbori de intervale Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.22 kb
// http://infoarena.ro/problema/arbint
#include <fstream>
using namespace std;

#define maxSize 100001

#define leftSon 2*node
#define rightSon 2*node+1

#define begin first
#define end second

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

int lenght,operations;
int position,value,maxim;
pair<int,int> interval;
int tree[4*maxSize+66];

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

int main() {
	in >> lenght >> operations;

	for(position=1;position<=lenght;position++) {
		in >> value;

		update(1,1,lenght);
	}

	for(int i=1;i<=operations;i++) {
		bool type;

		in >> type; // tipul de operatie
		if(type) {  // se cere updatarea unei valori
			in >> position >> value;
			update(1,1,lenght);
		}
		else {  // se cere maximul din interval
			in >> interval.begin >> interval.end;
			maxim = 0;  // maximul se reseteaza (numerele fiind pozitive)

			query(1,1,lenght);

			out << maxim << "\n";
		}
	}

	in.close();
	out.close();

	return (0);
}

void update(int node,int left,int right) {
	if(left == right) { // daca este interval elementar (s-a ajuns la pozitia cautata)
		// se efectueaza operatiile cerute
		// (in cazul de fata o atribuire)
		tree[node] = value;

		// se opreste apelul functiei pentru a evita
		// actualizarea nodului (vezi ultima linie din functie),
		// fii nodului nefiind creati (au valoarea zero)
		return;
	}
	else {
		int middle = (left + right) / 2;

		if(position <= middle)
			update(leftSon,left,middle);
		else
			update(rightSon,middle+1,right);
	}

    // se actualizeaza valoarea nodului
    // cu maximul dintre valorile fiilor
	tree[node] = max(tree[leftSon],tree[rightSon]);
}

void query(int node,int left,int right) {
    // daca nodul (intervalul nodului) este in intervalul cerut
	if(interval.begin <= left && right <= interval.end) {
        // se efectueaza operatiile cerute
		// (in cazul de fata gasirea maximului)
		if(maxim < tree[node])
			maxim = tree[node];
	}
	else {
		int middle = (left + right) / 2;

        // daca inceputul intervalului este in prima jumatate
		if(interval.begin <= middle)
			query(leftSon,left,middle);

        // daca sfarsitul intervalului este in a doua jumatate
        if(interval.end > middle)
			query(rightSon,middle+1,right);
	}
}