Problem:
Range Sum Query

Write a program which manipulates a sequence A = {a1, a2, . . . , an} with the following operations:

add(i, x): add x to ai.

getSum(s, t): print the sum of as, as+1,...,at.

Note that the initial values of ai (i = 1, 2, . . . , n) are 0.

Input

n q
com1 x1 y1
com2 x2 y2
...
comq xq yq

In the first line, n (the number of elements in A) and q (the number of queries) are given. Then, q queries are given where com represents the type of queries. '0' denotes add(xi, yi) and '1' denotes getSum(xi, yi).

Output

For each getSum operation, print the sum in a line.

Constraints

1 ≤ n ≤ 100000

1 ≤ q ≤ 100000

If comi is 0, then 1 ≤ xi ≤ n, 0 ≤ yi ≤ 1000.

If comi is 1, then 1 ≤ xi ≤ n, 1 ≤ yi ≤ n.

Sample Input 1

3 5
0 1 1
0 2 2
0 3 3
1 1 2
1 2 2

Sample Output 1

3
2

Solution in C++14 (judge verdict: Accepted)

#include <bits/stdc++.h>
using namespace std;

struct RSQ {
	using type = int;
	static const type id() { return 0; }
	static type op(const type& l, const type & r) { return l + r; }
};

const int PMAX = 3000000;

template <typename M>
class PersistentSegmentTree {
	using T = typename M::type;
	struct node {
		T val;
		node *l, *r;
		node() {}
		node(T val) : val(val), l(nullptr), r(nullptr) {}
		void init(T v, node *left, node *right) {
			val = v;
			l = left;
			r = right;
		}
	};
	const int n;
	vector<node> pool;
	int it;
	vector<node*> root;
	int size(int n) {
		int res = 1;
		while (res < n) res <<= 1;
		return res;
	}
	node *new_node(int val = 0, node *l = nullptr, node *r = nullptr) {
		pool[it].init(val, l, r);
		return &pool[it++];
	}
	node *fix(node *x, int p, T val, int lb, int ub) {
		if (p < lb || ub <= p) return x;
		if (lb + 1 == ub) return new_node(val);
		if (x == nullptr) x = new_node(M::id());
		else x = new_node(x->val, x->l, x->r);
		int c = (lb + ub) / 2;
		x->l = fix(x->l, p, val, lb, c);
		x->r = fix(x->r, p, val, c, ub);
		x->val = M::op(x->l == nullptr ? M::id() : x->l->val, x->r == nullptr ? M::id() : x->r->val);
		return x;
	}
	T sub(node *x, int l, int r, int lb, int ub) {
		if (x == nullptr || ub <= l || r <= lb) return M::id();
		if (l <= lb && ub <= r) return x->val;
		int c = (lb + ub) / 2;
		return M::op(sub(x->l, l, r, lb, c), sub(x->r, l, r, c, ub));
	}
public:
	PersistentSegmentTree(int n_) : n(size(n_)), pool(PMAX), it(0) {
		root.push_back(nullptr);
	}
	void update(int p, T val, int rt = -1) {
		if (rt == -1) rt = root.size() - 1;
		assert(0 <= rt && rt < (int)root.size());
		root.push_back(fix(root[rt], p, val, 0, n));
	}
	T find(int l, int r, int rt = -1) {
		if (rt == -1) rt = root.size() - 1;
		assert(0 <= rt && rt < (int)root.size());
		return sub(root[rt], l, r + 1, 0, n);
	}
	int getversion() {
		return root.size() - 1;
	}
};

int main()
{
	ios::sync_with_stdio(false), cin.tie(0);
	int n, q, com, x, y;
	cin >> n >> q;
	PersistentSegmentTree<RSQ> st(n);
	while (q--) {
		cin >> com >> x >> y;
		if (com) {
			printf("%d\n", st.find(x - 1, y - 1));
		}
		else {
			st.update(x - 1, st.find(x - 1, x - 1) + y);
		}
	}
	return 0;
}