Cod sursa(job #2754889)

Utilizator ChelaruPaulChelaru Paul ChelaruPaul Data 26 mai 2021 17:29:03
Problema Datorii Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.78 kb
#include<fstream>
#include <iostream>

#define ll long long
using namespace std;
ifstream fin("arbint.in");
ofstream fout("arbint.out");
int tree[4 * 100001];

int fiuStanga(int nod) {
    return 2 * nod;
}

int fiuDreapta(int nod) {
    return 2 * nod + 1;
}

void updateTree(int stanga, int dreapta, int poz, int val, int nodCurent) {
    if (stanga == dreapta) {
        tree[nodCurent] += val;
        return;
    }

    int mij = (stanga + dreapta) / 2;
    if (poz <= mij) updateTree(stanga, mij, poz, val, fiuStanga(nodCurent));
    else updateTree(mij + 1, dreapta, poz, val, fiuDreapta(nodCurent));

    tree[nodCurent] = tree[fiuStanga(nodCurent)] + tree[fiuDreapta(nodCurent)];
}


int query(int nodCurent, int st, int dr, int stNOU, int drNOU) {
    //daca face overlap total returnez valoarea de pe nodul curent
    if (stNOU <= st && drNOU >= dr)
        return tree[nodCurent];

    int mij = (st + dr) / 2;

    //daca pozitia noua din stanga e mai mare decat mijlocul intervaluilui -> subtree dreapta
    //else subtree left
    int s1 = 0, s2 = 0;
    if (stNOU <= mij) s1 = query(fiuStanga(nodCurent), st, mij, stNOU, drNOU);
    if (drNOU > mij) s2 = query(fiuDreapta(nodCurent), mij + 1, dr, stNOU, drNOU);

    return s1 + s2;
}

int main() {
    int nrNumere, val, actiuni;
    fin >> nrNumere >> actiuni;
    for (int i = 1; i <= nrNumere; i++) {
        fin >> val;
        updateTree(1, nrNumere, i, val, 1); //creez tree-ul pe valorile initiale
    }

    int actiune, poz, st, dr;
    for (int i = 0; i < actiuni; i++) {
        fin >> actiune;
        if (actiune == 1) {
            fin >> st >> dr;
            fout << query(1, 1, nrNumere, st, dr) << '\n';
        } else {
            fin >> poz >> val;
            updateTree(1, nrNumere, poz, -val, 1);
        }
    }
    return 0;
}