Cod sursa(job #2301109)

Utilizator CristyXtremeSimion Cristian CristyXtreme Data 12 decembrie 2018 17:42:04
Problema Arbori de intervale Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.53 kb
#include <stdio.h>

using namespace std;

inline int maxim(int a, int b) {
    if (a > b)
        return a;
    return b;
}

int construieste_arbint(int st, int dr, int *arb, int indice, int *A) {
    if (st == dr) {
        arb[indice] = A[st];
        return A[st];
    }
    int mij = st + (dr - st) / 2, a, b;
    a = construieste_arbint(st, mij, arb, 2 * indice + 1, A);           // mergem pe primul fiu in arbore, indexarea incepe de la 0 deci fiul stang va fi 2 * i + 1
    b = construieste_arbint(mij + 1, dr, arb, 2 * indice + 2, A);       // mergem pe al doilea fiu, cu indexul 2 * i + 2
    arb[indice] = maxim(a, b);
    return maxim(a, b);
}

void actualizeaza(int st, int dr, int a, int b, int *arb, int indice) {
    if (st == dr) {
        // daca limitele converg la pozitia ceruta, atunci actualizam valoarea din arbore cu noua valoare
        if (st == a)
            arb[indice] = b;
        return;
    }
    int mij = st + (dr - st) / 2;
    if (st <= a && a <= dr) {
        actualizeaza(st, mij, a, b, arb, 2 * indice + 1);
        actualizeaza(mij + 1, dr, a, b, arb, 2 * indice + 2);
        arb[indice] = maxim(arb[2 * indice + 1], arb[2 * indice + +2]);     //reactualizam maximul pe fiecare interval care continea pozitia a
    }
}

int interogheaza(int st, int dr, int a, int b, int *arb, int indice) {
    // daca intervalul [st, dr] e inclus in [a, b] inseamna ca trebuie sa luam toata "bucata"
    if (a <= st && dr <= b)
        return arb[indice];
    // daca nu, atunci cautam subintervalele de pe cei doi fii pana cand subintervalele se incadreaza in cerinta de mai sus
    int mij = st + (dr - st) / 2, x = -1, y = -1;
    if (a <= mij)
        x = interogheaza(st, mij, a, b, arb, indice * 2 + 1);
    if (b > mij)
        y = interogheaza(mij + 1, dr, a, b, arb, indice * 2 + 2);
    // este asigurat ca cel putin o data va merge pe una din ramuri, deci nu trebuie sa avem in vedere cazul cand si x si y sunt -1
    return maxim(x, y);
}

int main() {
	freopen("arbint.in", "r", stdin);
	freopen("arbint.out", "w", stdout);
	int n, m, cod, a, b;
	scanf("%d %d", &n, &m);
    int A[n], arb[4 * n - 1] = {0};
    for (int i = 0; i < n; i++)
        scanf("%d", &A[i]);
    arb[0] = construieste_arbint(0, n - 1, arb, 0, A);
    for (int i = 0; i < m; i++) {
        scanf("%d %d %d", &cod, &a, &b);
        if (cod == 0)
            printf("%d\n", interogheaza(0, n - 1, a - 1, b - 1, arb, 0));
        else
            actualizeaza(0, n - 1, a - 1, b, arb, 0);
    }
	return 0;
}