Cod sursa(job #3133471)

Utilizator dariutTache Daria dariut Data 25 mai 2023 18:43:01
Problema Datorii Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.61 kb
#include <iostream>
#include <vector>
#include <fstream>


struct SegmentTree {
    std::vector<long long> tree;
    int size;

    SegmentTree(int n) {
        size = 1;
        while (size < n) {
            size *= 2;
        }
        tree.resize(2 * size);
    }

    void build(const std::vector<int>& arr) {
        build(arr, 0, 0, size - 1);
    }

    void build(const std::vector<int>& arr, int node, int start, int end) {
        if (start == end) {
            if (start < arr.size()) {
                tree[node] = arr[start];
            }
            return;
        }

        int mid = (start + end) / 2;
        build(arr, 2 * node + 1, start, mid);
        build(arr, 2 * node + 2, mid + 1, end);
        tree[node] = tree[2 * node + 1] + tree[2 * node + 2];
    }

    void update(int index, int value) {
        update(index, value, 0, 0, size - 1);
    }

    void update(int index, int value, int node, int start, int end) {
        if (start == end) {
            tree[node] = value;
            return;
        }

        int mid = (start + end) / 2;
        if (index <= mid) {
            update(index, value, 2 * node + 1, start, mid);
        }
        else {
            update(index, value, 2 * node + 2, mid + 1, end);
        }
        tree[node] = tree[2 * node + 1] + tree[2 * node + 2];
    }

    long long query(int left, int right) {
        return query(left, right, 0, 0, size - 1);
    }

    long long query(int left, int right, int node, int start, int end) {
        if (start > right || end < left) {
            return 0;
        }

        if (start >= left && end <= right) {
            return tree[node];
        }

        int mid = (start + end) / 2;
        long long sumLeft = query(left, right, 2 * node + 1, start, mid);
        long long sumRight = query(left, right, 2 * node + 2, mid + 1, end);
        return sumLeft + sumRight;
    }
};

void calcDebt(int N, int M, std::vector<int>& debts, std::vector<std::pair<int, std::pair<int, int>>>& ops, std::ofstream& out) {
    SegmentTree segmentTree(N + 1);
    std::vector<int> cumulativeSum(N + 1);
    cumulativeSum[0] = debts[0];
    segmentTree.update(0, debts[0]);

    for (int i = 1; i <= N; ++i) {
        cumulativeSum[i] = cumulativeSum[i - 1] + debts[i];
        segmentTree.update(i, debts[i]);
    }

    for (const auto& operation : ops) {
        int opType = operation.first;
        int startDay = operation.second.first;
        int endDay = operation.second.second;

        if (opType == 0) {
            int day = startDay;
            int amount = endDay;
            debts[day] -= amount;
            segmentTree.update(day, debts[day]);

            for (int i = day + 1; i <= endDay; ++i) {
                cumulativeSum[i] -= amount;
                segmentTree.update(i, cumulativeSum[i]);
            }
        }
        else if (opType == 1) {
            long long totalDebt = segmentTree.query(startDay, endDay);
            out << totalDebt << std::endl;
        }
    }
}

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

    int N, M;
    in >> N >> M;

    std::vector<int> debts(N + 1);
    for (int i = 1; i <= N; ++i) {
        in >> debts[i];
    }

    std::vector<std::pair<int, std::pair<int, int>>> ops(M);
    for (int i = 0; i < M; ++i) {
        int opType;
        in >> opType;

        int arg1, arg2;
        in >> arg1 >> arg2;

        ops[i] = std::make_pair(opType, std::make_pair(arg1, arg2));
    }

    calcDebt(N, M, debts, ops, out);

    return 0;
}