Cod sursa(job #2805826)

Utilizator namesurname01Name Surname namesurname01 Data 22 noiembrie 2021 02:16:19
Problema Arbori de intervale Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.63 kb
/*Sursa urmareste modificarea succesiva a unor elemente dintr-un vector si aflarea maximului
din anumite intervale.
 Asadar, actualizarea se va realiza asupra unui singur element, iar interogarea asupra unui
interval.
*/

#include <stdio.h>
#include <algorithm>

using namespace std;

int arb[1 << 18]; //alegem k astfel incat 2^k<=2*N-1 pentru N=100000
int n, m, i, poz, a, b, x, op;

inline void actualizare(int nod, int st, int dr) {
    int m;

    if (st >= poz && dr <= poz) { //daca arb[nod] retine informatie despre un interval elementar
        arb[nod] = x; //modifcarea nodului
        return;
    }

    m = (st + dr) >> 1; //stabilim mijlocul intervalului
    if (poz <= m) actualizare(nod << 1, st, m); //actualizam fiul stanga;
    else actualizare((nod << 1) + 1, m + 1, dr); //actualizam fiul dreapta
    if (arb[nod << 1] < arb[(nod << 1) + 1]) arb[nod] = arb[(nod << 1) + 1];
    else arb[nod] = arb[nod << 1];//modificarea nodului
}

inline int interogare(int nod, int st, int dr) {
    int m, x1, x2;
    x1 = x2 = 0;
    if (a <= st && dr <= b)  //se verifica daca (st,dr) inclus in (a,b)
        return arb[nod]; //returnarea informatiei din nod;

    m = (st + dr) >> 1;
    if (a <= m) x1 = interogare(nod << 1, st, m); //interogare fiu stanga
    if (b > m)  x2 = interogare((nod << 1) + 1, m + 1, dr); //interogare fiu dreapta
    if (x2 > x1) x1 = x2; //update pt maximul din intervalul nodului
    return x1; //returnare informatie
}

int main() {
    freopen("arbint.in", "r", stdin);
    freopen("arbint.out", "w", stdout);
    scanf("%d%d", &n, &m); /* N-numarul de elem. al vectorului;
                            M-numarul de operatii(actualizare/interogare) efectuate
                        */
    for (i = 1; i <= n; i++) {
        scanf("%d", &x);  //citim elementele vectorului
        poz = i;           //si actualizam arborele de intervale de la st=1 la dr=n
        actualizare(1, 1, n);
    }

    for (i = 1; i <= m; i++) {
        scanf("%d%d%d", &op, &a, &b);
        /* op codifica tipul operatiei:
            op==0 => Se cere determinarea maximului pe intervalul (a,b);
            op==1 => Se cere modificarea elementului de pe pozitia a prin atribuirea valorii b;
        */
        if (op == 0) {
            printf("%d\n", interogare(1, 1, n)); //interogam intervalul (st,dr); intial st=1 & dr=n;
        }
        else {
            poz = a;
            x = b;
            actualizare(1, 1, n); /*actualizam intervalul (st,dr) - modificam intervalele care contin
            informatii despre elementul de pe pozitia poz;
            */
        }
    }
    return 0;
}