Cod sursa(job #3134038)

Utilizator Maria_VerdesVerdes Maria-Ioana Maria_Verdes Data 27 mai 2023 22:53:35
Problema Datorii Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.65 kb
#include <fstream>

using namespace std;

ifstream f("datorii.in");
ofstream g("datorii.out");

long long int arbore[60001];
int v[15001];

void constr(int indice, int st, int dr) //st si dr sunt capetele intervalului asociat nodului indice
{
    if(st == dr) //daca am ajuns intr-o frunza
    {
        arbore[indice] = v[st];
    }
    else { //daca suntem pe un interval
        constr(indice * 2, st, (st + dr) / 2); //construim subarborele stang
        constr(indice * 2 + 1, (st + dr) / 2 + 1, dr); //construim subarborele drept
        arbore[indice] = arbore[indice * 2] + arbore[indice * 2 + 1];
        //punem in nodul nostru suma dintre nodurile radacina ale celor doi subarbori
    }
}

void achitare(int indice_curent, int st, int dr, int indice, int val)
{
    //cu indice_curent ma plimb prin arbore, indice e cel din vector pe care trebuie sa-l modific
    if(st == dr)
    {
        //am ajuns in nodul frunza pe care il cautam
        v[indice] -= val;
        arbore[indice_curent] -= val;
    }
    else {
        //cautam indicele in arbore
        if(st <= indice && indice <= (st + dr) / 2) //daca e in intervalul asociat subarborelui stang
            achitare(indice_curent * 2, st, (st + dr) / 2, indice, val);
        else achitare(indice_curent * 2 + 1, (st + dr) / 2 + 1, dr, indice, val); //e in intervalul asociat subarborelui drept
        //reactualizam indicele nodului curent
        arbore[indice_curent] = arbore[indice_curent * 2] + arbore[indice_curent * 2 + 1];
    }
}

int suma(int indice, int st, int dr, int limInf, int limSup) //vr suma pe intervalul [limInf, limSup]
{
    //daca am iesit din intervalul cautat
    if(limSup < st || limInf > dr)
        return 0;
   if(limInf <= st && dr <= limSup) //daca acoperim complet intervalul curent
        return arbore[indice];
    //daca nu calculam suma pe subarbori
   return suma(indice * 2, st, (st + dr) / 2, limInf, limSup) + suma(indice * 2 + 1, (st + dr) / 2 + 1, dr, limInf, limSup);
}

int main()
{
    int n, m;
    f >> n >> m;
    for(int i = 1; i <= n; i++)
    {
        int element;
        f >> element;
        v[i] = element;
    }
    //construim arborele de intervale
    constr(1, 1, n);
    for(int i = 1; i <= m; i++)
    {
        int optiune, a, b;
        f >> optiune >> a >> b;
        switch(optiune)
        {
        case 0:
            {
                achitare(1, 1, n, a, b);
                break;
            }
        case 1:
            {
                g << suma(1, 1, n, a, b) << endl;
                break;
            }
        }
    }
    f.close();
    g.close();
    return 0;
}