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# (judge verdict: Accepted)

using System;
using System.Linq;

class Program
{
    static int n;
    static int q;

    static void Main()
    {
        int[] input = Console.ReadLine().Split().Select(int.Parse).ToArray();
        n = input[0];
        q = input[1];

        RSQ2 rsq = new RSQ2(n);
        for (int i = 0; i < q; i++)
        {
            input = Console.ReadLine().Split().Select(int.Parse).ToArray();
            int f = input[0];
            int s = input[1];
            int t = input[2];
            if (f == 0)
            {
                int x = input[3];
                rsq.Add(s - 1, t, x);
                continue;
            }
            Console.WriteLine(rsq.Query(s - 1, t));
        }
    }
}

struct RSQ2
{
    private int n;
    private long[] dat;
    private long[] lazy; // 遅延
    public int Length { get; private set; }

    /* nを要素数として、すべて0で初期化 */
    public RSQ2(int n)
    {
        Length = n;
        this.n = 1;
        while (this.n < n) this.n *= 2;
        dat = new long[2 * this.n - 1];
        lazy = new long[2 * this.n - 1];
    }

    /* k番目のノードについて遅延評価を行う */
    private void Eval(int k, int l, int r)
    {
        if (lazy[k] == 0) return;
        dat[k] += lazy[k];
        if (r - l > 1)
        {
            lazy[2 * k + 1] += lazy[k] / 2;
            lazy[2 * k + 2] += lazy[k] / 2;
        }
        lazy[k] = 0;
    }


    public void Add(int a, int b, long x, int k = 0, int l = 0, int r = -1)
    {
        if (r < 0) r = n;
        Eval(k, l, r);
        if (b <= l || r <= a) return;
        if (a <= l && r <= b)
        {
            lazy[k] += (r - l) * x;
            Eval(k, l, r);
        }
        else
        {
            Add(a, b, x, 2 * k + 1, l, (l + r) / 2);
            Add(a, b, x, 2 * k + 2, (l + r) / 2, r);
            dat[k] = dat[2 * k + 1] + dat[2 * k + 2];
        }
    }

    private long Query_(int a, int b, int k, int l, int r)
    {
        if (r <= a || b <= l) return 0;
        Eval(k, l, r);
        if (a <= l && r <= b) return dat[k];
        long v1 = Query_(a, b, k * 2 + 1, l, (l + r) / 2);
        long v2 = Query_(a, b, k * 2 + 2, (l + r) / 2, r);
        return v1 + v2;
    }

    /* [a,b)の和を求める */
    public long Query(int a, int b)
    {
        return Query_(a, b, 0, 0, n);
    }
}