Cod sursa(job #2975064)

Utilizator geezusIancur de Hunedoara geezus Data 5 februarie 2023 12:23:30
Problema Datorii Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.73 kb
#pragma region BRUH
#ifdef CLI
#include "iostream"
std::istream& in = std::cin;
std::ostream& out = std::cout;
#else
#include "fstream"
std::ifstream ________a ("datorii.in");
std::ofstream ________b ("datorii.out");
std::istream& in = ________a;
std::ostream& out = ________b;
#endif
#pragma endregion
#pragma region SEGMENT
#include <vector>
#include <functional>

namespace DataStructures {

    template < typename T, typename OT >
    class SegmentTree {
    public:
        struct Segment {
            const int left, right;
            bool isUnit() const { return right - left < 2; }
            int mid() const { return (right - left) / 2 + left; }
            std::pair<Segment, Segment> splitMiddle() const {
                int m = mid();
                return { {left, m}, {m, right} };
            }
        };

    private:
        std::function<OT(OT,OT)> op;
        const Segment all;
        std::vector<T> store;

        void update(const int id, const int position, const T& value, Segment current) {
            if(current.isUnit()) { store[id] = value; return; }

            const auto pair = current.splitMiddle();
            position < current.mid() ?
            update(id * 2, position, value, pair.first) :
            update(id * 2 + 1, position, value, pair.second) ;

            store[id] = op(store[id * 2], store[id * 2 + 1]);
        }

        OT query(const int id, const Segment target, const Segment current) const {
            if(target.right <= current.left || target.left >= current.right) return {};
            if(target.right >= current.right && target.left <= current.left) return store[id];
            const auto pair = current.splitMiddle();
            return op(query(id * 2, target, pair.first), query(id * 2 + 1, target, pair.second));
        }

    public:
        explicit SegmentTree(int len, std::function<OT(OT,OT)> operation) : all({0, len}),
                                                                            op(operation), store(4 * len + 1, {}) { }

        void update(const int position, const T& val) { update(1, position, val, all); }

        OT query(const int left, const int right) const { return query(1, {left, right}, all); }

        void resetStore() { std::fill(store.begin(), store.end(), {}); }
    };

} // DataStructures
#pragma endregion

int main() {
    int n, m; in >> n >> m;
    int arr[n];
    DataStructures::SegmentTree<int, int> seg(n, [](const int a, const int b) { return a + b; } );
    for(int i = 0; i < n; i++) { in >> arr[i]; seg.update(i, arr[i]); }
    for(int op, a, b; m; --m) {
        in >> op >> a >> b;
        a--;
        if(op == 0) {
            arr[a] -= b;
            seg.update(a, arr[a]);
        }
        else out << seg.query( a, b) << '\n';
    }
    return 0;
}