Cod sursa(job #2907721)

Utilizator mihnea.tTudor Mihnea mihnea.t Data 31 mai 2022 13:40:42
Problema Datorii Scor 80
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.43 kb
#include <bits/stdc++.h>

#define NMAX ((int)15e3)

#define LEFT(pos) ((pos * 2) + 1)
#define RIGHT(pos) ((pos + 1) * 2)

using namespace std;

ifstream fin("datorii.in");
ofstream fout("datorii.out");

int n, m;
int arr[NMAX + 1];
int seg_tree[5 * NMAX];

int rec_fill(int pos, int left, int right) {
    if (left == right) {
        seg_tree[pos] = arr[left];
        return seg_tree[pos];
    }

    int middle = left + ((right - left) >> 1);
    seg_tree[pos] = rec_fill(LEFT(pos), left, middle) +
        rec_fill(RIGHT(pos), middle + 1, right);

    return seg_tree[pos];
}

void create_segment_tree() {
    int h;
    for (h = 0; (1 << h) <= n; ++h);

    rec_fill(0, 0, n - 1);
}

int rec_query(int pos, int seg_left, int seg_right, int query_left, int query_right) {
    if (seg_right < query_left || query_right < seg_left) {
        return 0;
    }

    if (query_left <= seg_left && seg_right <= query_right) {
        return seg_tree[pos];
    }

    int middle = seg_left + ((seg_right - seg_left) >> 1);
    return rec_query(LEFT(pos), seg_left, middle, query_left, query_right) +
        rec_query(RIGHT(pos), middle + 1, seg_right, query_left, query_right);
}

int query(int left, int right) {
    --left;
    --right;
    return rec_query(0, 0, n - 1, left, right);
}

int rec_update(int pos, int left, int right, int arr_pos, int arr_value) {
    if (left > arr_pos || right < arr_pos) {
        return seg_tree[pos];
    }

    if (left == right) {
        seg_tree[pos] = arr_value;
        return seg_tree[pos];
    }

    int middle = left + ((right - left) >> 1);
    seg_tree[pos] = rec_update(LEFT(pos), left, middle, arr_pos, arr_value) +
        rec_update(RIGHT(pos), middle + 1, right, arr_pos, arr_value);

    return seg_tree[pos];
}

void update(int pos, int val_to_decrese) {
    --pos;
    arr[pos] -= val_to_decrese;
    rec_update(0, 0, n - 1, pos, arr[pos]);
}

int main(void) {
    fin >> n >> m;
    for (int i = 0; i < n; ++i) {
        fin >> arr[i];
    }

    // Create the segment tree
    create_segment_tree();

    for (int i = 0; i < m; ++i) {
        int op;
        fin >> op;

        switch (op) {
            case 1:
                int left, right;
                fin >> left >> right;
                fout << query(left, right) << "\n";
                break;

            case 0:
                int pos, val;
                fin >> pos >> val;
                update(pos, val);
                break;
        }
    }

    return 0;
}