Cod sursa(job #3357453)

Utilizator Cosma_Laura_IoanaCosma Laura-Ioana Cosma_Laura_Ioana Data 9 iunie 2026 20:41:37
Problema Arbori de intervale Scor 100
Compilator c-64 Status done
Runda Arhiva educationala Marime 2.72 kb
#include <stdio.h>
#define MAXN 100005

int tree[4 * MAXN]; // vectorul pentru arbore
int A[MAXN]; // vectorul A din enunt

int max(int a, int b)
{
    if (a>b) return a;
    else return b;
}

// Reprezentarea arborelui de intervale in vectorul tree:
// radacina e pe pozitia 1
// la pozitia 2*i - copilul stang al nodului i
// la pozitia 2*i+1 - copilul drept al nodului i

void build(int nod, int stanga, int dreapta)
{
    if (stanga == dreapta) // am ajuns la o frunza (1 singur element)
    {
        tree[nod] = A[stanga];
        return;
    }

    int mijloc = (stanga + dreapta) / 2;

    build(2 * nod, stanga, mijloc); // copilul stang
    build(2 * nod + 1, mijloc + 1, dreapta); // copilul drept

    // maximul de pe nodul curent = maximul dintre cei doi copii
    tree[nod] = max(tree[2 * nod], tree[2 * nod + 1]);
}

// Operatia de tip 1
void update(int nod, int stanga, int dreapta, int pozitie, int valoare_noua)
{
    if (stanga == dreapta) // am gasit elementul pe care vrem sa il modificam
    {
        tree[nod] = valoare_noua;
        return;
    }

    int mijloc = (stanga + dreapta) / 2;
    if (pozitie <= mijloc) // pozitia e in prima jumatate, mergem in copilul stang
        update(2 * nod, stanga, mijloc, pozitie, valoare_noua);
    else // pozitia e in a doua jumatate, mergem in copilul drept
       update(2 * nod + 1, mijloc + 1, dreapta, pozitie, valoare_noua);

    tree[nod] = max(tree[2 * nod], tree[2 * nod + 1]); // modificam arborele
}

// Operatia de tip 0
int find_max(int nod, int stanga, int dreapta, int a, int b)
{
    if (a <= stanga && b >= dreapta) // intervalul nodului e complet inclus in intervalul cerut => returnam valoarea
        return tree[nod];

    int mijloc = (stanga + dreapta) / 2;
    int maxim_gasit = -1;

    if (a <= mijloc) // intervalul cerut are o parte in stanga => cautam acolo
        maxim_gasit = max(maxim_gasit, find_max(2 * nod, stanga, mijloc, a, b));

    if (b > mijloc) // intervalul cerut are o parte in dreapta => cautam acolo
        maxim_gasit = max(maxim_gasit, find_max(2 * nod + 1, mijloc + 1, dreapta, a, b));

    return maxim_gasit;
}

int main(void)
{
    FILE *fin = fopen("arbint.in", "r");
    FILE *fout = fopen("arbint.out", "w");

    if (fin == NULL || fout == NULL) return 1;

    int N, M;
    fscanf(fin, "%d %d", &N, &M);

    for (int i = 1; i <= N; i++)
    {
        fscanf(fin, "%d", &A[i]);
    }

    build(1, 1, N); // construim arborele

    for (int i = 0; i < M; i++)
    {
        int operatie, a, b;
        fscanf(fin, "%d %d %d", &operatie, &a, &b);

        if (operatie == 0)
            fprintf(fout, "%d\n", find_max(1, 1, N, a, b));
        if (operatie == 1)
            update(1, 1, N, a, b);
    }

    fclose(fin);
    fclose(fout);
    return 0;
}