QinYulang @ 2024-10-31 22:33:14
#include <iostream>
#include <algorithm>
#define int unsigned long long
namespace qyl{
namespace seg{
constexpr int N = 1e5 + 5;
struct Node{
int sum;
int lc, rc;
int t;
};
Node tree[N << 2];
int root = 0, p = 0;
inline void insert(int &root, int l, int r, int L, int R, int v){
tree[++p].sum = tree[root].sum + (r - l + 1) * v;
tree[p].lc = tree[root].lc;
tree[p].rc = tree[root].rc;
tree[p].t = tree[root].t;
root = p;
if(l == L && r == R){
tree[root].t += v;
return ;
}
int mid = L + R >> 1;
if(r <= mid) insert(tree[root].lc, l, r, L, mid, v);
else if(l > mid) insert(tree[root].rc, l, r, mid + 1, R, v);
else insert(tree[root].lc, l, mid, L, mid, v), insert(tree[root].rc, mid + 1, r, mid + 1, R, v);
return ;
}
inline int query(int root, int l, int r, int L, int R, int sum){
if(l == L && r == R){
return tree[root].sum + sum * (r - l + 1);
}
int mid = L + R >> 1;
if(r <= mid) return query(tree[root].lc, l, r, L, mid, sum + tree[root].t);
else if(l > mid) return query(tree[root].rc, l, r, mid + 1, R, sum + tree[root].t);
else return query(tree[root].lc, l, mid, L, mid, sum + tree[root].t) + query(tree[root].rc, mid + 1, r, mid + 1, R, sum + tree[root].t);
}
inline void modify(int &root, int l, int r, int L, int R, int v){
tree[++p].sum = tree[root].sum + (r - l + 1) * v;
tree[p].lc = tree[root].lc;
tree[p].rc = tree[root].rc;
tree[p].t = tree[root].t;
root = p;
root = p;
if(l == L && r == R){
tree[root].t += v;
return ;
}
int mid = L + R >> 1;
if(r <= mid) modify(tree[root].lc, l, r, L, mid, v);
else if(l > mid) modify(tree[root].rc, l, r, mid + 1, R, v);
else modify(tree[root].lc, l, mid, L, mid, v), modify(tree[root].rc, mid + 1, r, mid + 1, R, v);
return ;
}
}
}
using namespace qyl;
signed main(){
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cout.tie(nullptr);
int n, q;
std::cin >> n >> q;
for(int i = 1; i <= n; i++){
int v;
std::cin >> v;
seg::insert(seg::root, i, i, 1, n, v);
}
while(q--){
int op, l, r, v;
std::cin >> op >> l >> r;
if(op == 1){
std::cin >> v;
seg::modify(seg::root, l, r, 1, n, v);
} else {
std::cout << seg::query(seg::root, l, r, 1, n, 0) << '\n';
}
}
return 0;
}