#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+5, mod = 1e9+7;
int a[N], n, q;
int tr[N*4], tag[N*4];

void build(int k, int l, int r){ // 第k个点,维护[l, r] 
	if(l == r) { // 叶子结点 
		tr[k] = a[l];// 区间只有一个数 
		return ; 
	}
	int mid = l + r >> 1;
	build(k*2, l, mid);
	build(k*2+1, mid+1, r);
	tr[k] = tr[k*2] + tr[k*2+1];
}
void upd(int k, int l, int r, int w){
	tr[k] += w * (r - l + 1);
	tag[k] += w;
}
void pushdown(int k, int l, int r){
	// tag[k]
	int mid = l + r >> 1;
	upd(k*2, l, mid, tag[k]);
	upd(k*2+1, mid+1, r, tag[k]);
	tag[k] = 0;
}
int query(int k, int l, int r, int x, int y){
	// 第k个点,维护[l, r]。 查询区间 [x, y] 
	if(x <= l && r <= y){
		return tr[k];
	}
	pushdown(k, l, r);
	int mid = l + r >> 1;
	int ans = 0; 
	if(x <= mid) { // 与左孩子有重叠 
		ans += query(k*2, l, mid, x, y);
	}
	if(y > mid){
		ans += query(k*2+1, mid+1, r, x, y);
	}
	return ans;
}

void modify(int k, int l, int r, int x, int y, int w){
	//第k个点,维护[l, r], 修改[x, y] 增加 w 
	if(x <= l && r <= y){
		tr[k] += w * (r - l + 1);
		tag[k] += w; // upd(k);
		return ;
	}
	pushdown(k, l, r);
	int mid = l + r >> 1;
	if(x <= mid) modify(k*2, l, mid, x, y, w);
	if(y > mid) modify(k*2+1, mid+1, r, x, y, w);
	tr[k] = tr[k*2] + tr[k*2+1];
} // O(n)


signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0); 
	cin >> n >> q;
	for(int i = 1; i <= n; i++) cin >> a[i];
	build(1, 1, n);
	while(q--){
		int op, l, r;
		cin >> op >> l >> r;
		if(op == 1) {
			int w;
			cin >> w;
			modify(1, 1, n, l, r, w);
		} else {
			cout << query(1, 1, n, l, r) << "\n";
		}
	}
	return 0;
}


0 条评论

目前还没有评论...