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

import java.util.*;

public class Main{

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int q = sc.nextInt();
        LazySegTree_RSQ seg = new LazySegTree_RSQ(n);
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < q; i++) {
            int a = sc.nextInt();
            int s = sc.nextInt() -1;
            int t = sc.nextInt();
            if(a == 0){
                int x = sc.nextInt();
                seg.add(s, t, x, 0, 0, seg.size);
            }else{
                sb.append(seg.sum(s, t, 0, 0, seg.size) + "\n");
            }
        }
        System.out.print(sb.toString());
        sc.close();

    }

}

class LazySegTree_RSQ {

    public int n;
    public int size;
    /**
     * 要素全体を含むノードのindex：0.
     * k番目(0-indexed)の要素のindex：k + size - 1
     * ノードkの親要素のindex：(k - 1) / 2.
     * ノードkの子要素のうち左側のindex：k*2+1.
     * ノードkの子要素のうち右側のindex：k*2+2.
     */
    public long[] data;
    public long[] lazy;

    /**
     * コンストラクタ.
     * @param n 要素数
     */
    public LazySegTree_RSQ(int n){
        this.n = n;
        size = 1;
        while(size < n) size *= 2;
        data = new long[size*2];
        lazy = new long[size*2];
    }

    /**
     * 指定したノードが遅延評価待ちの値を保持している場合、
     * 自ノードに反映し、子ノードの遅延評価待ちとして設定する。
     * @param k 自ノードのindex
     * @param l 自ノードの対象区間左側（含む）
     * @param r 自ノードの対象区間右側（含まない）
     */
    public void eval(int k, int l, int r){
        if(lazy[k] != 0){
            data[k] += lazy[k];
            if(1 < r - l){
                lazy[2*k+1]  += lazy[k] / 2;
                lazy[2*k+2]  += lazy[k] / 2;
            }
            lazy[k] = 0L;
        }
    }

    /**
     * 区間[a, b)での○○を求めます.
     * 最初に呼ぶ際は、query(a, b, x, 0, 0, size)として呼ぶ.
     * @param a 求める区間の下限（含む）
     * @param b 求める区間の上限（含まない）
     * @param k 確認するノードのindex
     * @param l 確認するノードの下限（含む）
     * @param r 確認するノードの上限（含まない）
     * @return 区間[a, b)での○○
     */
    public void add(int a, int b, int x, int k, int l, int r){
        eval(k, l, r);

        // 区間外
        if(b <= l || r <= a) return;

        // 完全に含む
        if(a <= l && r <= b){
            lazy[k] += (long)(r - l) * x;
            eval(k, l, r);
            return;
        }

        // それ以外
        add(a, b, x, 2*k+1, l, (l+r)/2);
        add(a, b, x, 2*k+2, (l+r)/2, r);
        data[k] = data[2*k+1] + data[2*k+2];
    }

    /**
     * 区間[a, b)の和を求めます.
     * 最初に呼ぶ際は、query(a, b, 0, 0, size)として呼ぶ.
     * @param a 求める区間の下限（含む）
     * @param b 求める区間の上限（含まない）
     * @param k 確認するノードのindex
     * @param l 確認するノードの下限（含む）
     * @param r 確認するノードの上限（含まない）
     * @return 区間[a, b)の和
     */
    public long sum(int a, int b, int k, int l, int r){
        // 区間外
        if(b <= l || r <= a) return 0;
        eval(k, l, r);
        // 完全に含む
        if(a <= l && r <= b) return data[k];
        // それ以外
        long vl = sum(a, b, 2*k+1, l, (l+r)/2);
        long vr = sum(a, b, 2*k+2, (l+r)/2, r);
        return vl + vr;
    }
}