'''
假设原始序列是b(0), b(1), b(2), ..... b(n-1)
对应的差分序列是a(0), a(1), a(2), ...... a(n-1)
区间数字都加上一个数,用树状数组维护a序列前缀和即可
第二问查询的是原序列的区段和, 如果能求原区段的前缀和,区段和也就解出来了
前缀和形式是 b(0) + b(1) + ...... b(x)
= a(0) +
a(0) + a(1)
....
a(0) + a(1) + ...... a(x)
= [a(0) + a(1) + a(x)] * (x+2) - [a(0) + 2a(1) + 3a(2) + ..... (x+1)a(x)]
因此,只需要维护a序列的前缀和以及 (i+1) * a(i) 序列的前缀和即可组合出
b序列的前缀和,继而b序列区间和也就求出来了
使用两个树状数组分别维护两个前缀和序列即可
'''
import sys
class FenwickTree:
def __init__(self, data):
if len(data) == 0:
raise ValueError('data length is zero!')
self.n = len(data)
prefix_sum = [0] * (self.n + 1)
self.sum_seg = [0] * (self.n + 1) # 分段存储的区间和 sum_seg[x]表示的是x位置结尾,长度为x&(-x)的区间中的数值的和
# 实际存储时候错一位存储,外部数据的下标从0开始,但是树状数组的下标是从1开始的
i = 1
for val in data:
prefix_sum[i] = prefix_sum[i-1] + val
self.sum_seg[i] = prefix_sum[i] - prefix_sum[i & (i-1)]
i += 1
# 获取x位置的原始数值
def getOrigValue(self, x):
x += 1
if x < 1 or x > self.n:
raise IndexError(f'error idx = {x}')
ans = self.sum_seg[x]
lca = x & (x-1) # 最近公共祖先
x -= 1
while x != lca:
ans -= self.sum_seg[x]
x &= (x-1)
return ans
# 获取区间[0, end]的数值和
def __getSumWithEnd(self, end): # 这里end是内部坐标,不是外部坐标
ans = 0
while end:
ans += self.sum_seg[end]
end &= (end - 1)
return ans
# 获取区间的数据和
def getSum(self, start, end):
start, end = start+1, end+1
if not (end >= start and start >= 1 and end <= self.n):
raise IndexError(f'bad range {(start-1, end-1)}')
if start == 1:
return self.__getSumWithEnd(end)
return self.__getSumWithEnd(end) - self.__getSumWithEnd(start-1)
# 更新x位置数值
def updateValue(self, x, val):
orig_val = self.getOrigValue(x)
x += 1
delta = val - orig_val
while x <= self.n:
self.sum_seg[x] += delta
x += x & (-x)
# x位置增加数值delta
def addValue(self, x, delta):
x += 1
while x <= self.n:
self.sum_seg[x] += delta
x += x & (-x)
n, m = map(int, input().split())
s = sys.stdin.readline()
arr = list(map(int, s.split()))
# 差分序列
sub = [0] * n
sub[0] = arr[0]
for i in range(1, n):
sub[i] = arr[i] - arr[i-1]
tree1 = FenwickTree(sub)
for i in range(n):
sub[i] *= (i+1)
tree2 = FenwickTree(sub)
for _ in range(m):
s = sys.stdin.readline()
if s[0] == 'C':
_, start, end, val = s.split()
start, end, val = int(start)-1, int(end)-1, int(val)
tree1.addValue(start, val)
tree2.addValue(start, val * (start + 1))
if end+1 < n:
tree1.addValue(end+1, -val)
tree2.addValue(end+1, -val*(end+2))
else:
_, start, end = s.split()
start, end = int(start)-1, int(end)-1
val_start = 0 if start == 0 else (start+1)*tree1.getSum(0, start-1) - tree2.getSum(0, start-1)
val_end = (end+2)*tree1.getSum(0, end) - tree2.getSum(0, end)
print(val_end - val_start)