Pagini recente » Cod sursa (job #909981) | Cod sursa (job #2683290) | Cod sursa (job #12616) | Cod sursa (job #250556) | Cod sursa (job #2909510)
#include <vector>
#include <cstdint>
#include <cassert>
#include <string>
/// #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'; }
}
}