Problem:
RSQ and RAQ

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

add(s, t, x): add x to as, as+1, ..., at.

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

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

Input

n q
query1
query2
:
queryq

In the first line, n (the number of elements in A) and q (the number of queries) are given. Then, ith query queryi is given in the following format:

0 s t x

or

1 s t

The first digit represents the type of the query. '0' denotes add(s, t, x) and '1' denotes getSum(s, t).

Output

For each getSum operation, print the sum;

Constraints

1 ≤ n ≤ 100000

1 ≤ q ≤ 100000

1 ≤ s ≤ t ≤ n

0 ≤ x < 1000

Sample Input 1

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

Sample Output 1

4
8

Sample Input 2

4 3
1 1 4
0 1 4 1
1 1 4

Sample Output 2

0
4

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

#include <vector>
#include <cassert>
#include <functional>

template<typename T>
struct BinaryIndexedTree {
	using value_type = T;
	using const_reference = const value_type &;
	using F = std::function<value_type(const_reference, const_reference)>;
	using size_type = std::size_t;
	
	BinaryIndexedTree(size_type n_, const F & f, const_reference id_elem) : n(n_), f(f), id_elem(id_elem) {
		node.resize(n + 1, id_elem);
	}
	
	size_type size() const noexcept {
		return n;
	}
	
	void add(size_type i, const_reference x) {
		assert(i < size());
		++i;
		for (; i <= size(); i += i & -i) node[i] = f(node[i], x);
	}
	
	// [0, i)
	value_type sum(size_type i) const {
		assert(i <= size());
		value_type res = id_elem;
		for (; i > 0; i -= i & -i) res = f(res, node[i]);
		return res;
	}
	
	// sum[0, r] \leq x を満たす最小の r を返す (存在しなければ size())
	size_type lower_bound(const_reference x) const {
		size_type res = 0;
		size_type s = id_elem, w = 1;
		while (w < size()) w <<= 1;
		for (; w > 0; w >>= 1) {
			if (res + w <= size()) {
				value_type cur = f(s, node[res + w]);
				if (cur < x) {
					res += w;
					s = cur;
				}
			}
		}
		return res;
	}
	
private:
	size_type n;
	F f;
	value_type id_elem;
	std::vector<value_type> node;
};


#include <vector>
#include <cassert>
#include <functional>

template<typename T, template<typename> class U>
struct BinaryIndexedTree_RangeAdd {
	using bit_type = U<T>;
	using value_type = typename bit_type::value_type;
	using const_reference = typename bit_type::const_reference;
	using size_type = typename bit_type::size_type;
	
	BinaryIndexedTree_RangeAdd(size_type n) : n(n) {
		bit.resize(2, bit_type(n, [](auto && x, auto && y) { return x + y; }, 0));
	}
	
	size_type size() const noexcept {
		return n;
	}
	
	// [l, r) += x
	void add(size_type l, size_type r, const_reference x) {
		assert(l < r);
		assert(r <= size());
		bit[0].add(l, x);
		bit[0].add(r - 1, -x);
		bit[1].add(l, -x * (static_cast<value_type>(l) - 1));
		bit[1].add(r - 1, x * (r - 1));
	}
	
	// \Sum_{ k = [0, i) } a_k
	value_type sum(size_type i) {
		assert(i <= size());
		return bit[0].sum(i) * (static_cast<value_type>(i) - 1) + bit[1].sum(i);
	}
	
	// \Sum_{ k = [l, r) } a_k
	value_type sum(size_type l, size_type r) {
		assert(l < r);
		assert(r <= size());
		return sum(r) - sum(l);
	}
	
private:
	size_type n;
	std::vector<bit_type> bit;
};

#include <cstdio>
int main() {
	int n, q;
	scanf("%d %d", &n, &q);
	
	using ll = long long;
	
	BinaryIndexedTree_RangeAdd<ll, BinaryIndexedTree> bit(n);
	while (q--) {
		int query, s, t;
		scanf("%d %d %d", &query, &s, &t);
		--s;
		if (query == 0) {
			int x;
			scanf("%d", &x);
			bit.add(s, t, x);
		}
		else {
			printf("%lld\n", bit.sum(s, t));
		}
	}
	return 0;
}