#include
<
stdio.h
>
#include
<
stdlib.h
>
#define
L(t) ((t) << 1)
#define
R(t) ((t) << 1 | 1)
#define
ll long long
#define
MAXN 100000
struct
SegTree{
int
l,r;
ll add, sum;
int
getMid(){
return
( l
+
r)
>>
1
;
}
int
getDis(){
return
r
-
l
+
1
;
}
}tree[MAXN
<<
2
];
int
val[
100010
];
void
bulid(
int
left,
int
right,
int
t){
tree[t].l
=
left;
tree[t].r
=
right;
tree[t].add
=
0
;
if
(left
==
right){
tree[t].sum
=
val[left];
return
;
}
int
mid
=
tree[t].getMid();
bulid(left, mid, L(t));
bulid(mid
+
1
, right, R(t));
tree[t].sum
=
tree[L(t)].sum
+
tree[R(t)].sum;
}
void
update(
int
left,
int
right,
int
a,
int
t){
if
( left
<=
tree[t].l
&&
right
>=
tree[t].r ){
tree[t].add
+=
a;
//
覆盖这个区间 add增加 同时更新sum 这时add表示子树要增加的增量
tree[t].sum
+=
a
*
tree[t].getDis();
return
;
}
if
( tree[t].add ){
//
如果增量不为空,向下传递,同时更新儿子的sum值,最后清空自己的增量
tree[L(t)].sum
+=
tree[L(t)].getDis()
*
tree[t].add;
tree[R(t)].sum
+=
tree[R(t)].getDis()
*
tree[t].add;
tree[L(t)].add
+=
tree[t].add;
tree[R(t)].add
+=
tree[t].add;
tree[t].add
=
0
;
}
int
mid
=
tree[t].getMid();
if
(right
<=
mid ){
update(left, right, a, L(t));
}
else
if
(left
>
mid ){
update(left, right, a, R(t));
}
else
{
update(left, mid, a, L(t));
update(mid
+
1
, right, a, R(t));
}
tree[t].sum
=
tree[L(t)].sum
+
tree[R(t)].sum ;
//
递归回来后 由左右孩子的sum值更新父亲的sum值
}
ll query(
int
left,
int
right,
int
t){
if
(left
<=
tree[t].l
&&
right
>=
tree[t].r ){
return
tree[t].sum;
}
if
( tree[t].add ){
//
同理
tree[L(t)].sum
+=
tree[L(t)].getDis()
*
tree[t].add;
tree[R(t)].sum
+=
tree[R(t)].getDis()
*
tree[t].add;
tree[L(t)].add
+=
tree[t].add;
tree[R(t)].add
+=
tree[t].add;
tree[t].add
=
0
;
}
int
mid
=
tree[t].getMid();
if
(right
<=
mid ){
return
query(left, right, L(t));
}
else
if
( left
>
mid ){
return
query(left, right, R(t));
}
else
{
return
query(left, mid ,L(t))
+
query(mid
+
1
, right, R(t));
}
}
int
main(){
char
cmd[
3
];
int
n, q;
scanf(
"
%d%d
"
,
&
n,
&
q);
for
(
int
i
=
1
; i
<=
n;
++
i){
scanf(
"
%d
"
,
&
val[i]);
}
bulid(
1
, n,
1
);
//
不要每次都忘掉 !
for
(
int
i
=
1
; i
<=
q;
++
i){
scanf(
"
%s
"
,cmd);
if
(cmd[
0
]
==
'
Q
'
){
int
a, b;
scanf(
"
%d %d
"
,
&
a,
&
b);
ll ans
=
query(a, b,
1
);
printf(
"
%lld\n
"
,ans);
}
else
{
int
a, b, c;
scanf(
"
%d%d%d
"
,
&
a,
&
b,
&
c);
update(a, b, c,
1
);
}
}
return
0
;
}