typedef long long ll;
const ll N = 1e5 + 82;
ll n, a[N], Tree[N << 2], lazy_tag[N], Q;
inline void lazy_tag_move (ll node, ll l, ll r, ll k)
{
lazy_tag[node] += k;
Tree[node] += k * (r - l + 1);
}
inline void push_up (ll node)
{
Tree[node] = Tree[node << 1] + Tree[node << 1 | 1];
}
inline void push_down (ll node, ll l, ll r)
{
if (lazy_tag[node])
{
ll mid = (l + r) >> 1;
lazy_tag_move (node << 1, l, mid, lazy_tag[node]);
lazy_tag_move (node << 1 | 1, mid + 1, r, lazy_tag[node]);
lazy_tag[node] = 0;
}
}
void build (ll node, ll l, ll r)
{
lazy_tag[node] = 0;
if (l == r)
{
Tree[node] = a[l];
return;
}
ll mid = l + r >> 1;
build (node << 1, l, mid);
build (node << 1 | 1, mid + 1, r);
push_up (node);
}
void update (ll nodel, ll noder, ll l, ll r, ll node, ll k)
{
if (nodel <= l && r <= noder)
{
lazy_tag_move (node, l, r, k);
return;
}
push_down (node, l, r);
ll mid = (l + r) >> 1;
if (nodel <= mid)
update (nodel, noder, l, mid, node << 1, k);
if (noder > mid)
update (nodel, noder, mid + 1, r, node << 1 | 1, k);
push_up(node);
}
ll query (ll query_l, ll query_r, ll l, ll r, ll node)
{
if (query_l <= l && r <= query_r)
return Tree[node];
ll mid = l + r >> 1, ans = 0;
push_down (node, l, r);
if (query_l <= mid)
ans += query (query_l, query_r, l, mid, node << 1);
if (query_r > mid)
ans += query (query_l, query_r, mid + 1, r, node << 1 | 1);
return ans;
}
int main ()
{
freopen ("P3372_8.in", "r", stdin);
// freopen ("P3372_8.out", "w", stdout);
scanf ("%lld %lld", &n, &Q);
for (int i = 1; i <= n; i ++)
scanf ("%lld", &a[i]);
build (1, 1, n);
while (Q --)
{
int query_type;
scanf ("%d", &query_type);
if (query_type == 1)
{
ll l, r, k;
scanf ("%lld %lld %lld", &l, &r, &k);
update (l, r, 1, n, 1, k);
}
else if (query_type == 2)
{
ll l, r;
scanf ("%lld %lld", &l, &r);
printf ("%lld\n", query (l, r, 1, n, 1));
}
}
return 0;
}
#8 #9 #10 WA, 68ms.