Pagini recente » Cod sursa (job #1762461) | Cod sursa (job #166099) | Cod sursa (job #1080548) | Cod sursa (job #214872) | Cod sursa (job #2312418)
/*
* 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;
}