Cod sursa(job #3246442)

Utilizator DunareTanasescu Luca-Ioan Dunare Data 3 octombrie 2024 08:59:48
Problema Datorii Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.5 kb
#include <iostream>
#include <fstream>
using namespace std;
ifstream f("datorii.in");
ofstream g("datorii.out");
int N, M;
int MaxArb[400070];
int start, finish, Val, Pos, valint;

void Gen(int nod, int st, int dr)
/// functie care se apeleaza intotdeauna (1,1,N), unde n e nr de frunze
/// in Val se va stoca valoarea ce trebuie stocata/modificata
/// in Pos se va stoca pozitia pe care se va pune val
{
    if(st == dr)///primul element
    {
        MaxArb[nod] = Val;///se adauga in varf
        return;
    }
    ///Pos - pozitia pe care trebuie adaugat/modificat elementul
    int div = (st + dr) / 2;
    if(Pos <= div)/// alege pe care ramura sa o ia
        Gen(2 * nod, st, div);
    else  /// se apeleaza recursiv pentru copilul potrivit, unde trebuie adaugat
        Gen(2 * nod + 1, div + 1, dr);
    ///cerinte in functie de problema, aici sa aflam maximul
    MaxArb[nod] = MaxArb[2 * nod] + MaxArb[2 * nod +1];

}
void Update(int nod, int st, int dr)
{
    if(st == dr)///primul element
    {
        MaxArb[nod] = MaxArb[nod]- Val;///se adauga in varf
        return;
    }
    int div = (st + dr) / 2;
    if(Pos <= div)
        Update(2 * nod, st, div);
    else
        Update(2 * nod + 1, div + 1, dr);
    MaxArb[nod] = MaxArb[2 * nod] + MaxArb[2 * nod +1];

}

void interogare(int nod, int st, int dr)
/// se apeleaza intotdeauna cu interogare(1,1,N), N-nr de frunze
/// in start se va stoca de unde incepe intervalul
/// in finish va stoca limita superioara a intervalului
{
    if(start <= st && dr <= finish)///orice interval dinauntrul [st,dr]
    {
        valint += MaxArb[nod];///verifica maximul
        ///cout<<MaxArb[nod]<<' ';
        ///se adapteaza in fct de pb
        return;
    }
    int div = (st + dr) / 2;
    if(start <= div) ///avanseaza pe copilul din st
        interogare(2 * nod, st, div);
    if(div < finish) ///avanseaza pe copilul din dreapta
        interogare(2 * nod + 1, div + 1, dr);
    ///!!! poate avansa pe ambii copii, deci ifuri fara else
}

int main()
{
    int n,a,b,m,caz;
    f>>n>>m;
    for(int i=1;i<=n;i++)
    {
        Pos=i;f>>Val;
        Gen(1,1,n);
    }
    for(int i=1;i<=m;i++)
    {
        f>>caz>>a>>b;
        if(caz==1)
        {
            valint=0;
            start=a;finish=b;
            interogare(1,1,n);
            g<<valint<<'\n';
            ///cout<<'\n';
        }
        else{
            Pos=a;Val=b;
            Update(1,1,n);
        }

    }
    return 0;
}