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 <iostream>
#include <algorithm>
#include <array>
#include <cstdint>
#include <functional>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <stdlib.h>
#include <string>
#include <time.h>
#include <utility>
#include <vector>

#define INF 1000000000
#define MOD 1000000007
#define rep(i,a,b) for(uint32 i = (a); i < (b); ++i)
#define bitget(a,b) (((a) >> (b)) & 1)
#define ALL(x) (x).begin(),(x).end()
#define C(x) std::cout << #x << " : " << x << std::endl
#define scanf scanf_s

using int32 = std::int_fast32_t;
using int64 = std::int_fast64_t;
using uint32 = std::uint_fast32_t;
using uint64 = std::uint_fast64_t;
template<typename Monoid, typename Operand>
struct RBnode {
	RBnode *ch[2], *par;
	Monoid value, sum;
	Operand lazy;
	uint32 size, height;
	bool color, reversed;//true=black
};
template<typename Monoid, typename Operand>
class RBTrees {
	using Node = RBnode<Monoid, Operand>;
public:
	std::vector<Node> nodes;
	uint32 itr;
	bool balanced;
	Monoid insdata;
	RBTrees(size_t maxsize) {
		nodes.resize(maxsize + 1);
		itr = 0;
		nodes[0].ch[0] = &nodes[0];
		nodes[0].ch[1] = &nodes[0];
		nodes[0].par = nullptr;
		nodes[0].size = 0;
		nodes[0].height = 1;
		nodes[0].color = 1;
	}
	Node *nil(void) {
		return &nodes[0];
	}
	Node *create(Monoid &value) {
		nodes[++itr].ch[0] = &nodes[0];
		nodes[itr].ch[1] = &nodes[0];
		nodes[itr].par = nullptr;
		nodes[itr].value = value;
		nodes[itr].sum = value;
		nodes[itr].lazy.inactive();
		nodes[itr].size = 1;
		nodes[itr].height = 2;
		nodes[itr].color = 1;
		nodes[itr].reversed = 0;
		return &nodes[itr];
	}
	Node *update(Node *node) {
		node->sum = node->value;
		node->height = node->color + 1;
		if (node->ch[0] != &nodes[0]) {
			push(node->ch[0]);
			node->sum = node->ch[0]->sum + node->sum;
			node->height = node->ch[0]->height + node->color;
		}
		if (node->ch[1] != &nodes[0]) {
			push(node->ch[1]);
			node->sum = node->sum + node->ch[1]->sum;
			node->height = node->ch[1]->height + node->color;
		}
		node->size = node->ch[0]->size + 1 + node->ch[1]->size;
		node->ch[0]->par = node;
		node->ch[1]->par = node;
		return node;
	}
	Node *push(Node *node) {
		node->ch[0]->lazy = node->ch[0]->lazy * node->lazy;
		node->ch[1]->lazy = node->ch[1]->lazy * node->lazy;
		node->value = node->value * node->lazy;
		node->sum = node->sum * node->lazy;
		node->lazy.inactive();
		if (node->reversed) {
			node->ch[0]->reversed ^= 1;
			node->ch[1]->reversed ^= 1;
			std::swap(node->ch[0], node->ch[1]);
			node->sum.reverse();
			node->value.reverse();
			node->reversed = 0;
		}
		return node;
	}
	Node *rotate(Node *node, uint32 dir) {
		Node *t = node->ch[dir ^ 1];
		node->ch[dir ^ 1] = t->ch[dir];
		t->color = node->color;
		node->color = 0;
		t->ch[dir] = update(node);
		t->par = nullptr;
		return update(t);
	}
	Node *insert(Node *root, const Monoid &value, uint32 position) {
		insdata = value;
		root = _subins(root, position);
		if (!root->color) {
			root->height += 1;
			root->color = 1;
		}
		return root;
	}
	Node *_subins(Node *node, uint32 pos) {
		if (node == &nodes[0]) {
			create(insdata);
			nodes[itr].color = 0;
			nodes[itr].height = 1;
			balanced = 1;
			return &nodes[itr];
		}
		push(node);
		if (node->ch[0]->size < pos) {
			node->ch[1] = _subins(node->ch[1], pos - node->ch[0]->size - 1);
			if (balanced) {
				return _inbal(update(node), 1);
			}
		}
		else {
			node->ch[0] = _subins(node->ch[0], pos);
			if (balanced) {
				return _inbal(update(node), 0);
			}
		}
		return update(node);
	}
	Node *flip(Node *node) {
		node->ch[0]->color = 1;
		node->ch[0]->height += 1;
		node->ch[1]->color = 1;
		node->ch[1]->height += 1;
		node->color = 0;
		return node;
	}
	Node *_inbal(Node *node, uint32 dir) {
		if (!node->color) {
			return node;
		}
		if (!node->ch[dir]->ch[dir ^ 1]->color) {
			node->ch[dir] = rotate(node->ch[dir], dir);
		}
		if (node->ch[dir]->ch[dir]->color) {
			balanced = 0;
			return node;
		}
		if (node->ch[dir ^ 1]->color) {
			balanced = 0;
			return rotate(node, dir ^ 1);
		}
		return flip(node);
	}
	Node *access(Node *root, uint32 position) {
		while (1) {
			if (position > root->ch[0]->size) {
				position -= root->ch[0]->size + 1;
				root = root->ch[1];
			}
			else if (position < root->ch[0]->size) {
				root = root->ch[0];
			}
			else {
				return root;
			}
		}
	}
	Node *erase(Node *root, uint32 position) {
		push(root);
		if (root->ch[0]->size > position) {
			root->ch[0] = erase(root->ch[0], position);
			if (balanced) {
				return _erbal(update(root), 0);
			}
			return update(root);
		}
		else if (root->ch[0]->size < position) {
			root->ch[1] = erase(root->ch[1], position - root->ch[0]->size - 1);
			if (balanced) {
				return _erbal(update(root), 1);
			}
			return update(root);
		}
		if (root->ch[0] != &nodes[0]) {
			if (root->ch[1] != &nodes[0]) {
				root->ch[1] = erase(root->ch[1], 0);
				root->value = insdata;
				if (balanced) {
					return _erbal(update(root), 1);
				}
				return update(root);
			}
			root->ch[0]->color = 1;
			++root->ch[0]->height;
			balanced = 0;
			return root->ch[0];
		}
		else {
			insdata = root->value;
			if (root->ch[1] != &nodes[0]) {
				root->ch[1]->color = 1;
				++root->ch[1]->height;
				balanced = 0;
				return root->ch[1];
			}
			balanced = root->color;
			return &nodes[0];
		}
	}
	Node *_erbal(Node *node, uint32 dir) {
		if (node->ch[dir ^ 1]->ch[0]->color&&node->ch[dir ^ 1]->ch[1]->color) {
			node->height = node->ch[dir ^ 1]->height + node->color;
			if (node->ch[dir ^ 1]->color) {
				if (node->color) {
					node->ch[dir ^ 1]->color = 0;
					node->ch[dir ^ 1]->height -= 1;
					node->height -= 1;
					return node;
				}
				node->ch[dir ^ 1]->color = 0;
				node->ch[dir ^ 1]->height -= 1;
				node->color = 1;
				balanced = 0;
				return node;
			}
			node = rotate(node, dir);
			node->ch[dir] = _erbal(node->ch[dir], dir);
			node->height = node->ch[dir]->height + node->color;
			return node;
		}
		balanced = 0;
		if (node->ch[dir^1]->ch[dir^1]->color) {
			node->ch[dir ^ 1] = rotate(node->ch[dir ^ 1], dir ^ 1);
		}
		node = rotate(node, dir);
		++node->height;
		++node->ch[0]->height;
		node->ch[0]->color = 1;
		++node->ch[1]->height;
		node->ch[1]->color = 1;
		return node;
	}
	Monoid range(Node *root, uint32 begin, uint32 end) {
		Node *t = root;
		Monoid ret;
		while (1) {
			if (t->ch[0]->size < begin) {
				begin -= t->ch[0]->size + 1;
				end -= t->ch[0]->size + 1;
				t = t->ch[1];
				continue;
			}
			if (t->ch[0]->size < end) {
				end -= t->ch[0]->size + 1;
				ret = t->value;
				root = t->ch[0];
				t = t->ch[1];
				break;
			}
			t = t->ch[0];
		}
		while (root != &nodes[0]) {
			if (root->ch[0]->size < begin) {
				begin -= root->ch[0]->size + 1;
				root = root->ch[1];
				continue;
			}
			if(root->ch[1]!=&nodes[0]) ret = (root->value + root->ch[1]->sum) + ret;
			else ret = root->value + ret;
			root = root->ch[0];
		}
		while (t != &nodes[0]) {
			if (t->ch[0]->size < end) {
				end -= t->ch[0]->size + 1;
				if(t->ch[0]!=&nodes[0]) ret = ret + (t->ch[0]->sum + t->value);
				else ret = ret + t->value;
				t = t->ch[1];
				continue;
			}
			t = t->ch[0];
		}
		return ret;
	}
	void show(Node *node) {
		std::cout << "(";
		if (node->ch[0] != &nodes[0]) {
			show(node->ch[0]);
			std::cout << "←";
		}
		std::cout << node->value.e << " " << node->color << " " << node->height;
		if (node->ch[1] != &nodes[0]) {
			std::cout << "→";
			show(node->ch[1]);
		}
		std::cout << ")";
		return;
	}
};
struct SUB {
	int64 e;
	bool a;
	SUB() { set(); }
	SUB(int64 x, bool y) { e = x; a = y; }
	void set() { a = false; }
	void inactive(void) {
		a = false;
		return;
	}
	SUB operator*(const SUB &other) {
		if (other.a) return other;
		return *this;
	}
};
struct SUM {
	int64 e;
	int64 s;
	SUM() { set(); }
	SUM(int64 x, int64 y) { e = x;s = y; }
	void set() { e = 0; s = 1; }
	void reverse(void) {
		return;
	}
	SUM operator+(const SUM &other) {
		return  SUM(e + other.e, s + other.s);
	};
	SUM operator*(const SUB &other) {
		if (other.a) return SUM(s*other.e, s);
		return *this;
	}
};
int main(void) {
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);
	uint32 n, q;
	std::cin >> n >> q;
	RBTrees<SUM, SUB> T(n + q);
	RBnode<SUM, SUB> *r = T.nil();
	int64 com, y;
	uint32 x;
	rep(i, 0, n) {
		r = T.insert(r, SUM(0, 1), 0);
	}
	//T.show(r);
	//std::cout << "\n";
	rep(i, 0, q) {
		std::cin >> com >> x >> y;
		if (com == 0) {
			y = y + T.access(r, x - 1)->value.e;
			r = T.erase(r, x - 1);
			//T.show(r);
			//std::cout << "\n";
			r = T.insert(r, SUM(y, 1), x - 1);
			//T.show(r);
			//std::cout << "\n";
		}
		else {
			std::cout << T.range(r, x - 1, y).e << "\n";
		}
	}
	return 0;
}