YMnRb @ 2023-10-19 22:30:10
#include <cstdio>
#include <iostream>
struct tree
{
struct node
{
int l, r;
long long val, addsum = 0;
bool flag = 0;
}*t;
void build(const int& x, const int& l, const int& r)
{
t[x].l = l, t[x].r = r;
if (l == r)
{
scanf("%lld", &t[x].val);
return;
}
build(x << 1, l, l + r >> 1);
build(x << 1 | 1, (l + r >> 1) + 1, r);
t[x].val = t[x << 1].val + t[x << 1 | 1].val;
return;
}
tree(const int& len = 2)
{
t = new node[len << 2];
build(1, 1, len);
return;
}
inline void adddown(const int& x)
{
if (t[x].l == t[x].r)
{
t[x].val += t[x].addsum;
t[x].addsum = t[x].flag = 0;
return;
}
t[x << 1].addsum += t[x].addsum;
t[x << 1].val += t[x].addsum * (t[x << 1].r - t[x << 1].l + 1);
t[x << 1 | 1].addsum += t[x].addsum;
t[x << 1 | 1].val += t[x].addsum * (t[x << 1 | 1].r - t[x << 1 | 1].l + 1);
t[x << 1].flag = t[x << 1 | 1].flag = 1;
t[x].addsum = t[x].flag = 0;
}
void add(const int& x, const long long& val, const int& l, const int& r)
{
if (t[x].r < l || r < t[x].l)
return;
if (l <= t[x].l && t[x].r <= r)
{
t[x].flag = 1;
t[x].addsum += val;
t[x].val += t[x].addsum * (t[x].r - t[x].l + 1);
return;
}
add(x << 1, val, l, r);
add(x << 1 | 1, val, l, r);
t[x].val = t[x << 1].val + t[x << 1 | 1].val;
}
long long query(const int& x, const int& l, const int& r)
{
if (t[x].r < l || r < t[x].l)
return 0;
if (l <= t[x].l && t[x].r <= r)
return t[x].val;
if (t[x].flag)
adddown(x);
return query(x << 1, l, r) + query(x << 1 | 1, l, r);
}
};
int main(void)
{
std::ios::sync_with_stdio(false);
int n, m, op, x, y;
long long k;
scanf("%d %d", &n, &m);
tree t(n);
while (m--) {
scanf("%d %d %d", &op, &x, &y);
if (op == 1)
scanf("%lld", &k), t.add(1, k, x, y);
else
printf("%lld\n", t.query(1, x, y));
}
return 0;
}