Cod sursa(job #2311829)

Utilizator dragomir_ioanDragomir Ioan dragomir_ioan Data 3 ianuarie 2019 18:50:27
Problema Arbori de intervale Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.33 kb
/*
 * Arbori de intervale
 * https://infoarena.ro/problema/arbint
 *
 */

#include <iostream>

#define STANGA(i) ((i) * 2)
#define DREAPTA(i) ((i) * 2 + 1)
#define TATA(i) ((i) / 2)

#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) > (b) ? (b) : (a))

int m, n;
int v[100001];
int maxim[100000 * 17];	// un pic mai mult decat n*log(n)
int unde_incepe[100000 * 17], unde_se_termina[100000 * 17];
int leaf_index[100001];

int construieste_arbore_initial(int de_la, int pana_la, int radacina) {
	if(de_la > pana_la)
		return -1;

	unde_incepe[radacina] = de_la;
	unde_se_termina[radacina] = pana_la;

	if(de_la == pana_la) {
		leaf_index[de_la] = radacina;
		return maxim[radacina] = v[de_la];
	}

	int mijloc = (de_la + pana_la) / 2;
	int max_stanga = construieste_arbore_initial(de_la, mijloc, STANGA(radacina)),
		max_dreapta = construieste_arbore_initial(mijloc+1, pana_la, DREAPTA(radacina));

	return maxim[radacina] = Max(max_stanga, max_dreapta);
}

int query(int de_la, int pana_la, int radacina) {
	//std::cerr << "query de la " << de_la << " pana la " << pana_la << " pe radacina " << radacina << "[" << unde_incepe[radacina] << ", " << unde_se_termina[radacina] << "]" << std::endl;
	int m = -1;

	if(de_la <= unde_incepe[radacina] && pana_la >= unde_se_termina[radacina]) {
		return maxim[radacina];
	}

	int mijloc = (unde_incepe[radacina] + unde_se_termina[radacina]) / 2;

	if(de_la <= mijloc) {
		int x = query(de_la, mijloc, STANGA(radacina));
		m = Max(m, x);
	}

	if(pana_la >= mijloc+1) {
		int x = query(mijloc+1, pana_la, DREAPTA(radacina));
		m = Max(m, x);
	}

	return m;
}

void update_intervalele_care_contin(int i) {
	int poz = leaf_index[i];

	maxim[poz] = v[i];
	poz = TATA(poz);

	while(poz != 0) {
		maxim[poz] = Max(maxim[STANGA(poz)], maxim[DREAPTA(poz)]);
		poz = TATA(poz);
	}
}

int main() {
	freopen("arbint.in", "r", stdin);
	freopen("arbint.out", "w", stdout);

	int i;

	std::cin >> n >> m;
	for(i=1; i<=n; i++) {
		std::cin >> v[i];
	}

	construieste_arbore_initial(1, n, 1);
	
	//for(int j=1; j<=n*2; j *= 2) {
	//	for(i=j; i<j*2; i++) {
	//		//std::cerr << maxim[i] << " ";
	//	}
	//	//std::cerr << std::endl;
	//}

	for(i=0; i<m; i++) {
		int op, a, b;
		std::cin >> op >> a >> b;

		if(op == 0) {
			std::cout << query(a, b, 1) << std::endl;
		} else {
			v[a] = b;
			update_intervalele_care_contin(a);
		}
	}

	return 0;
}