Cod sursa(job #2983278)

Utilizator VDAVIDVladuca david VDAVID Data 22 februarie 2023 00:18:35
Problema Arbori de intervale Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.43 kb
#include <bits/stdc++.h>

using namespace std;

const int NMAX = 1e5 + 1;
vector<int> v(NMAX), tree(4 * NMAX);
int n, m;

/// practic, fac ca la divide_et_impera
void build(int nod, int st, int dr) {
    if(st == dr)
        tree[nod] = v[st];
    else {
        int mij = (st + dr) / 2;
        build(nod * 2, st, mij); // construiesc partea stanga
        build(nod * 2 + 1, mij + 1, dr); // construiesc partea dreapta
        tree[nod] = max(tree[nod*2], tree[nod*2+1]);
    }
}

void update(int nod, int st, int dr, int poz, int val) {
    if(st == dr)
        tree[nod] = val;
    else {
        int mij = (st + dr) / 2;
        if(poz <= mij) // verific daca se afla in partea stanga
            update(nod * 2, st, mij, poz, val); // dau update partea stanga
        else
            update(nod * 2 + 1, mij + 1, dr, poz, val); // dau update partea dreapta
        tree[nod] = max(tree[nod*2], tree[nod*2+1]);
    }
}

/**
    Ce inseamna fiecare variabila?

    Ex : Fie [1, 5] -> intervalul total
    st = limita din stanga al intervalului total -> 1
    dr = limita din dreapta al intervalului total -> 5

    caut maximul pe intervalul [2, 4] :
    query_st = limita din stanga al intervalului -> 2
    query_dr = limita din dreapta al intervalului -> 4

**/

int query(int nod, int st, int dr, int query_st, int query_dr) {
    /// total overleap -> returnez rezultatul
    if(query_st <= st && dr <= query_dr)
        return tree[nod];

    /// no overleap -> mergem in cealalta parte
    int mij = (st + dr) / 2, ans = 0;
    if(query_dr <= mij) // ma uit daca se afla total in stanga
        return query(nod * 2, st, mij, query_st, query_dr);
    if(query_st >= mij + 1) // ma uit daca se afla total in dreapta
       return query(nod * 2 + 1, mij + 1, dr, query_st, query_dr);

    /// partial overleap -> ne uitam in ambele parti
    int max_st = query(nod * 2, st, mij, query_st, query_dr);
    int max_dr = query(nod * 2 + 1, mij + 1, dr, query_st, query_dr);
    return max(max_st, max_dr);
}

int main() {
    ifstream cin("arbint.in");
    ofstream cout("arbint.out");
    cin >> n >> m;
    for(int i = 1; i <= n; i++)
        cin >> v[i];
    build(1, 1, n);
    for(int i = 1; i <= m; i++) {
        int c, a, b;
        cin >> c >> a >> b;
        if(c == 0)
            cout << query(1, 1, n, a, b) << '\n';
        else
            update(1, 1, n, a, b);
    }
    return 0;
}