Cod sursa(job #2312424)

Utilizator dragomir_ioanDragomir Ioan dragomir_ioan Data 4 ianuarie 2019 20:33:21
Problema Arbori de intervale Scor 100
Compilator c-64 Status done
Runda Arhiva educationala Marime 1.99 kb
/*
 * Arbori de intervale
 * https://infoarena.ro/problema/arbint
 *
 */

#include <stdio.h>

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

inline int Max(int a, int b) {
	return a > b ? a : b;
}

inline int Min(int a, int b) {
	return a < b ? a : b;
}

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) {
	int m = -1;

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

	int mijloc = (rad_stanga + rad_dreapta) / 2;

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

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

	return m;
}

inline 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;

	scanf("%d%d", &n, &m);
	for(i=1; i<=n; i++) {
		scanf("%d", &v[i]);
	}

	construieste_arbore_initial(1, n, 1);

	for(i=0; i<m; i++) {
		int op, a, b;
		scanf("%d%d%d", &op, &a, &b);

		if(op == 0) {
			printf("%d\n", query(a, b, 1, 1, n));
		} else {
			v[a] = b;
			update_intervalele_care_contin(a);
		}
	}

	printf("\n");

	return 0;
}