#include using namespace std; using ll = long long; // clang-format off #define rep(i, n) for (ll i = 0; i < ll(n); i++) #define drep(i, n) for (ll i = ll(n - 1); i >= 0; i--) #define rng(a) (a).begin(), (a).end() #define rrng(a) (a).rbegin(), (a).rend() #define sz(x) (ll)(x).size() #define cto const auto& #define popcount __builtin_popcount #ifdef _DEBUG #include #define deb(...) debug_print::multi_print(#__VA_ARGS__, __VA_ARGS__) #else #define deb(...) (static_cast(0)) #endif template inline bool chmin(T& x, const T& y) { return x > y ? x = y, 1 : 0; } template inline bool chmax(T& x, const T& y) { return x < y ? x = y, 1 : 0; } template inline void print_vec(const vector& x) { rep(i, sz(x)) cout << x[i] << " \n"[i+1==sz(x)]; } template inline void uniq_vec(vector& x) { sort(rng(x)); x.erase(unique(rng(x)), x.end()); } inline void FASTER_IO() { cin.tie(0)->sync_with_stdio(false); cout << fixed << setprecision(20); } // clang-format on using ld = long double; using P = pair; constexpr char el = '\n'; constexpr int INF = 1001001001; constexpr ll LINF = 2e18; constexpr int mod = 1000000007; // 1. A set S equipped with a binary operation S × S → S // 2. Associativity // 3. Identity element template class DynamicSegmentTree { using F = function; struct Node; using Node_ptr = unique_ptr; struct Node { size_t idx; Monoid val, product; Node_ptr left, right; Node(size_t idx, Monoid val) : idx(idx), val(val), product(val), left(nullptr), right(nullptr) {} void update(const DynamicSegmentTree& x) { const auto& combine = x.combine; const auto& id = x.identity; product = combine(combine(left ? left->product : id, val), right ? right->product : id); } }; const size_t n; Node_ptr root; F combine; Monoid identity; void set(Node_ptr& t, size_t l, size_t r, size_t i, Monoid val) const { if (!t) { t = make_unique(i, val); return; } if (t->idx == i) { t->val = val; t->update(*this); return; } size_t mid = (l + r) >> 1; if (i < mid) { if (t->idx < i) swap(t->idx, i), swap(t->val, val); set(t->left, l, mid, i, val); } else { if (t->idx > i) swap(t->idx, i), swap(t->val, val); set(t->right, mid, r, i, val); } t->update(*this); } Monoid get(const Node_ptr& t, size_t l, size_t r, size_t i) const { if (!t) return identity; if (t->idx == i) return t->val; size_t mid = (l + r) >> 1; return i < mid ? get(t->left, l, mid, i) : get(t->right, mid, r, i); } Monoid fold(const Node_ptr& t, size_t a, size_t b, size_t l, size_t r) const { if (!t || b <= l || r <= a) return identity; if (l <= a && b <= r) return t->product; size_t c = (a + b) >> 1; Monoid res = fold(t->left, a, c, l, r); if (l <= t->idx && t->idx && t->idx < r) res = combine(res, t->val); return combine(res, fold(t->right, c, b, l, r)); } public: DynamicSegmentTree(size_t n, const F& combine, Monoid identity) : n(n), combine(combine), identity(identity), root(nullptr) {} void set(size_t i, Monoid val) { set(root, 0, n, i, val); } Monoid get(size_t i) const { return get(root, 0, n, i); } Monoid fold(size_t l, size_t r) const { return fold(root, 0, n, l, r); } Monoid all_fold() const { return root ? root->product : identity; } }; int main() { FASTER_IO(); DynamicSegmentTree seg( 1e10 + 5, [](ll x, ll y) { return x + y; }, 0ll); int q; cin >> q; ll ans = 0; while (q--) { int type; cin >> type; if (type == 0) { ll x, y; cin >> x >> y; seg.set(x, seg.get(x) + y); } else { ll l, r; cin >> l >> r; ans += seg.fold(l, r + 1); } } cout << ans << el; return 0; }