不能正确计算答案
// fhq Threap
// 按照下标分裂
#include <iostream>
using namespace std;
#define N 100100
#define siz(x) tr[x].siz
#define sum(x) tr[x].sum
#define val(x) tr[x].val
#define ls(x) tr[x].ls
#define rs(x) tr[x].rs
struct node {
int val = 0;
int add = 0;
int sum = 0;
int siz = 1;
int w = 0;
int ls, rs;
};
node tr[N];
inline void pushup(int x) {
siz(x) = siz(ls(x)) + siz(rs(x)) + 1;
sum(x) = sum(ls(x)) + sum(rs(x)) + val(x);
}
inline void pushdown(int x) {
if (ls(x)) {
sum(ls(x)) += siz(ls(x)) * tr[x].add;
val(ls(x)) += tr[x].add;
tr[ls(x)].add += tr[x].add;
}
if (rs(x)) {
sum(rs(x)) += siz(rs(x)) * tr[x].add;
val(rs(x)) += tr[x].add;
tr[rs(x)].add += tr[x].add;
}
tr[x].add = 0;
}
void split(int x, int k, int& va, int& vb) {
if (!x) {
va = vb = 0;
return;
}
pushdown(x);
if (siz(ls(x)) < k) {
va = x;
// split(rs(x), k - (siz(ls(x)) + 1), rs(x), vb);
split(rs(x), k - siz(ls(x)) - 1, rs(x), vb);
} else {
vb = x;
split(ls(x), k, va, ls(x));
}
pushup(x);
}
int merge(int x, int y) {
if (!x || !y) {
return x | y;
}
if (tr[x].w <= tr[y].w) {
pushdown(x);
rs(x) = merge(rs(x), y);
pushup(x);
return x;
} else {
pushdown(y);
ls(y) = merge(x, ls(y));
pushup(y);
return y;
}
}
int tot = 0;
inline int nn(int k) {
tot++;
sum(tot) = k;
val(tot) = k;
siz(tot) = 1;
tr[tot].w = rand();
return tot;
}
int a[N];
int n;
int root = 0;
inline void add(int l, int r, int k) {
int a, b, c;
split(root, l - 1, a, b);
split(b, r - l + 1, b, c);
//现在a=[1,l-1],b=[l,r],c=[r+1,n];
sum(b) += k * siz(b);
val(b) += k;
tr[b].add += k;
root = merge(merge(a, b), c);
}
int qsum(int l, int r) {
int a, b, c;
split(root, l - 1, a, b);
split(b, r - l + 1, b, c);
int ret = tr[b].sum;
root = merge(merge(a, b), c);
return ret;
}
int m;
signed main() {
cin >> n >> m;
for (int i = 1; i <= n; i++) {
cin >> a[i];
root = merge(root, nn(a[i]));
}
for (int i = 1; i <= m; i++) {
int o;
cin >> o;
if (o == 1) {
int x, y, k;
cin >> x >> y >> k;
add(x, y, k);
} else {
int x, y;
cin >> x >> y;
cout << qsum(x, y) << endl;
// cout << tr[root].sum << endl;
}
// cout << root << " " << sum(root) << endl;
}
return 0;
}