Cod sursa(job #2903344)

Utilizator AndreiAncutaAndrei Ancuta AndreiAncuta Data 17 mai 2022 14:43:31
Problema Datorii Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.66 kb
#include <fstream>
#include <vector>

class SegmentTree {
protected:
    std::vector<int> tree;
    int length;

    void build(const std::vector<int> &nums, int node, int l, int r) {
        if (l == r) {
            tree[node] = nums[l];
            return;
        }

        int mid = l + (r - l) / 2;
        build(nums, node * 2 + 1, l, mid);
        build(nums, node * 2 + 2, mid + 1, r);
        tree[node] = tree[node * 2 + 1] + tree[node * 2 + 2];
    }

    long long sum_range(int node, int l, int r, int ql, int qr) {
        if (ql > qr) {
            return 0;
        }

        if (l == ql && r == qr) {
            /* ::printf("Sum [%d..%d], query [%d, %d]\n", l, r, ql, qr); */
            return tree[node];
        }

        int mid = l + (r - l) / 2;

        long long s = 0;
        auto new_qr = std::min(qr, mid);
        if (ql <= new_qr) {
            s += sum_range(2 * node + 1, l, mid, ql, new_qr);
        }
        auto new_ql = std::max(ql, mid + 1);
        if (new_ql <= qr) {
            s += sum_range(2 * node + 2, mid + 1, r, new_ql, qr);
        }

        /* ::printf("Sum [%d..%d], query [%d, %d]\n", l, r, ql, qr); */
        return s;
    }

    void subtract(int index, int val, int node, int l, int r) {
        if (l == r) {
            /* ::printf("Update [%d..%d] = %d - %d = %d\n", l, r, tree[node], val, tree[node] - val); */
            tree[node] -= val;
            return;
        }

        int mid = l + (r - l) / 2;

        if (index <= mid) {
            subtract(index, val, 2 * node + 1, l, mid);
        } else {
            subtract(index, val, 2 * node + 2, mid + 1, r);
        }

        tree[node] = tree[node * 2 + 1] + tree[node * 2 + 2];
        /* ::printf("Update [%d..%d] = %d\n", l, r, tree[node]); */
    }

public:
    SegmentTree(const std::vector<int> &nums) : length(nums.size()) {
        tree.resize(4 * nums.size());
        build(nums, 0, 0, length - 1);
    }

    long long sum_range(int ql, int qr) {
        return sum_range(0, 0, length - 1, ql, qr);
    }

    void subtract(int index, int val) { subtract(index, val, 0, 0, length - 1); }
};

int main() {
    std::ifstream ifs("datorii.in");

    int n, m;
    ifs >> n >> m;

    std::vector<int> nums(n);

    for (int i = 0; i < n; ++i) {
        ifs >> nums[i];
    }

    SegmentTree segment_tree(nums);

    std::ofstream ofs("datorii.out");

    for (int q = 0; q < m; ++q) {
        int op, arg1, arg2;
        ifs >> op >> arg1 >> arg2;

        if (op == 0) {
            segment_tree.subtract(arg1 - 1, arg2);
        } else {
            ofs << segment_tree.sum_range(arg1 - 1, arg2 - 1) << '\n';
        }
    }

    ifs.close();
    ofs.close();

    return 0;
}