Cod sursa(job #2312418)

Utilizator dragomir_ioanDragomir Ioan dragomir_ioan Data 4 ianuarie 2019 20:24:56
Problema Arbori de intervale Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.25 kb
/*
 * Arbori de intervale
 * https://infoarena.ro/problema/arbint
 *
 */

#include <iostream>
#include <cstdio>

#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 leaf_index[100001];

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

	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, int rad_stanga, int rad_dreapta) {
	//std::cerr << "query de la " << de_la << " pana la " << pana_la << " pe radacina " << radacina << "[" << rad_stanga << ", " << rad_dreapta << "]" << std::endl;
	int m = -1;

	if(de_la <= rad_stanga && pana_la >= rad_dreapta) {
		//std::cerr << "Tot" << std::endl;
		return maxim[radacina];
	}

	int mijloc = (rad_stanga + rad_dreapta) / 2;

	if(de_la <= mijloc) {
		//std::cerr << "Stanga" << std::endl;
		int x = query(de_la, Min(mijloc, pana_la), STANGA(radacina), rad_stanga, mijloc);
		m = Max(m, x);
	}

	if(pana_la >= mijloc+1) {
		//std::cerr << "Dreapta" << std::endl;
		int x = query(Max(de_la, mijloc+1), pana_la, DREAPTA(radacina), mijloc+1, rad_dreapta);
		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(i=0; i<m; i++) {
		int op, a, b;
		std::cin >> op >> a >> b;

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

	std::cout << std::endl;

	return 0;
}