Cod sursa(job #2754858)

Utilizator Andreea__Zavoiu Andreea Andreea__ Data 26 mai 2021 16:51:33
Problema Datorii Scor 20
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.45 kb
// el poate fi solicitat sa raspunda cat mai repede la intrebarea: ce suma de bani a ramas inca neachitata
//  =>  trb sa cunoasca suma pe intervale de zile   => arbori de intervale
// eu citesc pentru fiecare din cele n zile suma neachitata inca din ziua respectiva => asta va fi valoarea din noduri

#include <iostream>
#include <fstream>
using namespace std;
ifstream fin("datorii.in");
ofstream fout("datorii.out");

int stree[400002], s;  // segment tree

void update(int i, int st, int dr, int poz, int val)
{
    if (st == dr) {
        stree[i] += val; // la nodul i pun valoarea data (initial am numai 0 => pun aduna)
        return;
    }

    int mij = (st + dr) / 2;
    if (poz <= mij) // aleg subarborele in care sa caut pozitia la care sa inserez valoarea data
        update (2*i, st, mij, poz, val); // fiul stang
    else
        update (2*i+1, mij + 1, dr, poz, val); // fiul drept

    stree[i] = stree[2*i] + stree[2*i + 1] ; // in nod se alege suma dintre cei 2 fii
}

void query(int i, int st, int dr, int x, int y)
{
    // If segment of this node is a part of the given range, then return the min of the segment
    if (x <= st && y >= dr){
        s += stree[i];
        return ;
    }


    // If a part of this segment overlaps with the given range
    int mij = ( st + dr )  / 2;

    int suma1 = 0, suma2 = 0;

    if (x <= mij)
        query(2*i, st, mij, x, y);
    if (y > mij)
        query(2*i+1, mij + 1, dr, x, y);
}

// Obs: indexarea in cerinta e de la 1 !
int main()
{
    int n, m, a, op, b, val;
    fin >> n >> m;
    for (int i=1; i<=n; i++)
    {
        fin >> a;
        update(1, 1, n, i, a); // pune valoarea a la pozitia i, parcurgand nodurile de la 1 la n incepand cu 1
    }

    for (int i=0; i<m; i++)
    {
        fin >> op;
        if (op==0)  // achitare = update pe interval  -> scade val de la pozitia i
        {
            fin >> i >> val;
            update(1, 1, n, i, -val);    // pentru ca folosesc aceeasi functie ca la constructia arborelui, unde in fiecare nod adun valoarea citita,
        }                               // aici ca sa scad suma platita din suma initiala din nod, trebuie sa trimit valoarea cu minus ca sa faca scadere in loc de adunare
        else   // query pe interval
        {
            fin >> a >> b;
            s=0; query(1, 1, n, a, b);
            fout << s << '\n';   // suma pe intervalul a b
        }
    }
    return 0;
}