Cod sursa(job #2909509)

Utilizator redstonegamer22Andrei Ion redstonegamer22 Data 14 iunie 2022 01:17:33
Problema Datorii Scor 40
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.42 kb
#define _GLIBCXX_DEBUG
#include <vector>
#include <cstdint>
#include <cassert>
#include <string>
#include <bits/stdc++.h>

/// #define NDEBUG

namespace ja::AdvancedDataStructures::SegmentTree {
	#ifndef jassert
		#define jassert(expr, msg, ...) assert(expr && msg)
	#endif // jassert
	#ifndef jlog
		#define jlog(...) ((void)0)
	#endif // jlog

	template < typename DATA, typename OPS >
	class PointUpdateRangeQuery {
	private:
		std::vector<DATA> data;
		int32_t offset;
		OPS op{};

		void _set(int32_t poz, DATA val) {
			data[poz + offset] = val;
			for(poz = (poz + offset) / 2; poz > 0; poz /= 2)
				data[poz] = op.sum(data[2 * poz], data[2 * poz + 1]);
		}

		DATA _get(int32_t poz) {
			return data[poz + offset];
		}

		void _update(int32_t poz, DATA val) {
			data[poz + offset] = op.sum(data[poz + offset], val);
			for(poz = (poz + offset) / 2; poz > 0; poz /= 2)
				data[poz] = op.sum(data[2 * poz], data[2 * poz + 1]);
		}

		DATA _query(int32_t l, int32_t r) {
			DATA ret = op.zero();
			l = l + offset; r = r + offset;

			while(l < r) {
				if(l & 1) { ret = op.sum(ret, data[l]); l += 1; } // l is a right child, include it
				if(r & 1) { r -= 1; ret = op.sum(ret, data[r]); } // r is a right child, exclude it
				l /= 2; r /= 2;
			}

			return ret;
		}

	public:
		PointUpdateRangeQuery(int32_t n) {
		    offset = 1;
			while(offset < n) offset *= 2;
			data.resize(2 * offset, op.zero());
		};

		void set(int32_t position, DATA value) {
			jassert(0 <= position && position < offset, "position is out of bounds", position, offset);
			_set(position, value);
		}

		DATA get(int32_t position) {
			jassert(0 <= position && position < offset, "position is out of bounds", position, offset);
			return _get(position);
		}

		void update(int32_t position, DATA change) {
			jassert(0 <= position && position < offset, "position is out of bounds", position, offset);
			_update(position, change);
		}

		DATA query(int32_t left, int32_t right) {
			jassert(0 <= left && left <= right && right + 1 < offset, "left and right are not correct", left, right, offset);
			return _query(left, right + 1);
		}

		std::string to_string() {
			std::string ret = "[ ";
			for(int i = 1; i < data.size(); i++) {
				if((i & (i - 1)) == 0) { // i is the first node on its level
					if(i != 1) { // doesn't matter for the root
						ret = ret + " | ";
					}
				}
				ret = ret + std::to_string(i) + ": " + std::to_string(data[i]);
				if(((i + 1) & i) != 0) { // i is not the last node on its level
					ret = ret + ", ";
				}
			}
			ret = ret + " ]";
			return ret;
		}
	};
};

#include <bits/stdc++.h>

using namespace std;


#ifdef INFOARENA

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

#define cin in
#define cout out

#endif // INFOARENA

struct ops {
    inline int64_t zero() const { return 0LL; }
    inline int64_t sum(int64_t a, int64_t b) { return a + b; }
};

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);

    ja::AdvancedDataStructures::SegmentTree::PointUpdateRangeQuery<int64_t, ops> aib(15000);

    int n, m; cin >> n >> m;
    for(int i = 1; i <= n; i++) {
        int x; cin >> x;
        aib.set(i, x);
    }

    while(m--) {
        int op, a, b; cin >> op >> a >> b;
        if(op == 0) { aib.update(a, -b); }
        if(op == 1) { cout << aib.query(a, b) << '\n'; }
    }
}