Cod sursa(job #3358255)

Utilizator nedeleavladNedelea Vlad-Matei nedeleavlad Data 15 iunie 2026 21:18:34
Problema Arbori de intervale Scor 100
Compilator c-64 Status done
Runda Arhiva educationala Marime 2.74 kb
#include <stdio.h>
#define MAXN 100005

int n, m, v[MAXN], arb[4 * MAXN];

// construim arborele: fiecare nod retine maximul din intervalul sau
void build(int nod, int st, int dr)
{
    // daca am ajuns la o frunza, punem valoarea din vector
    if (st == dr)
    {
        arb[nod] = v[st];
        return;
    }
    // impartim intervalul in doua jumatati
    int mij = (st + dr) / 2;
    // construim prima jumatate (stanga)
    build(2*nod, st, mij);
    // construim a doua jumatate (dreapta)
    build(2*nod+1, mij+1, dr);
    // maximul din nodul curent e maximul dintre cei doi fii
    arb[nod] = arb[2*nod] > arb[2*nod+1] ? arb[2*nod] : arb[2*nod+1];
}

// returnam maximul din intervalul [a, b]
int query(int nod, int st, int dr, int a, int b)
{
    // daca intervalul nodului e complet inclus in [a,b], returnam direct
    if (a <= st && dr <= b)
        return arb[nod];
    // altfel impartim in stanga si dreapta
    int mij = (st + dr) / 2, rez = 0, x;
    // mergem in stanga doar daca intervalul [a,b] se suprapune cu stanga
    if (a <= mij)
    {
        x = query(2*nod, st, mij, a, b);
        // retinem maximul gasit pana acum
        if (x > rez) rez = x;
    }
    // mergem in dreapta doar daca intervalul [a,b] se suprapune cu dreapta
    if (b > mij)
    {
        x = query(2*nod+1, mij+1, dr, a, b);
        // retinem maximul gasit pana acum
        if (x > rez) rez = x;
    }
    return rez;
}

// modificam valoarea de pe pozitia poz cu val, si refacem maximele pe drum
void update(int nod, int st, int dr, int poz, int val)
{
    // am ajuns la frunza, modificam valoarea
    if (st == dr)
    {
        arb[nod] = val;
        return;
    }
    // impartim intervalul in doua jumatati
    int mij = (st + dr) / 2;
    // daca pozitia e in jumatatea stanga, mergem acolo
    if (poz <= mij)
        update(2*nod, st, mij, poz, val);
    // altfel mergem in jumatatea dreapta
    else
        update(2*nod+1, mij+1, dr, poz, val);
    // dupa ce am modificat jos, refacem maximul pentru nodul curent
    arb[nod] = arb[2*nod] > arb[2*nod+1] ? arb[2*nod] : arb[2*nod+1];
}

int main()
{
    FILE *fin = fopen("arbint.in", "r");
    FILE *fout = fopen("arbint.out", "w");
    fscanf(fin, "%d %d", &n, &m);
    for (int i = 1; i <= n; i++)
        fscanf(fin, "%d", &v[i]);
    build(1, 1, n); // construim arborele pentru tot vectorul
    for (int i = 0; i < m; i++)
    {
        int tip, a, b;
        fscanf(fin, "%d %d %d", &tip, &a, &b);
        if (tip == 0)
            fprintf(fout, "%d\n", query(1, 1, n, a, b)); // tip 0 = query
        else
            update(1, 1, n, a, b);                        // tip 1 = update
    }
    fclose(fin);
    fclose(fout);
    return 0;
}