rt,我不会线段树,所以只好打了个分块,结果就过了。
建议加大数据范围。
#include <bits/stdc++.h>
#define int int64_t
#define maxn 131072
using namespace std;
int a[maxn], n, ms, q;
int s[maxn], m[maxn], b[maxn], e[maxn], add[maxn], siz[maxn];
namespace block{
void build();
void update(int, int, int);
int query(int, int);
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
cin >> n >> ms;
q = sqrt(n);
for (int i = 1; i <= n; i++)
cin >> a[i];
block::build();
for (int i = 1; i <= ms; i++) {
int mode, x, y, k;
cin >> mode;
if (mode == 1) {
cin >> x >> y >> k;
block::update(x, y, k);
} else {
cin >> x >> y;
cout << block::query(x, y) << "\n";
}
}
return 0;
}
void block::build() {
for (int i = 1; i <= q; i++) {
b[i] = n / q * (i - 1) + 1;
e[i] = n / q * i;
}
e[q] = n;
for (int i = 1; i <= q; i++)
siz[i] = e[i] - b[i] + 1;
for (int i = 1; i <= q; i++)
for (int j = b[i]; j <= e[i]; j++)
m[j] = i;
for (int i = 1; i <= q; i++)
for (int j = b[i]; j <= e[i]; j++)
s[i] += a[j];
}
void block::update(int x, int y, int k) {
if (m[x] == m[y]) {
for (int i = x; i <= y; i++) {
s[m[i]] += k;
a[i] += k;
}
} else {
for (int i = x; i <= e[m[x]]; i++) {
s[m[i]] += k;
a[i] += k;
}
for (int i = b[m[y]]; i <= y; i++) {
s[m[i]] += k;
a[i] += k;
}
for (int i = m[x] + 1; i < m[y]; i++)
add[i] += k;
}
}
int block::query(int x, int y) {
int q = 0;
if (m[x] == m[y]) {
for (int i = x; i <= y; i++)
q += a[i] + add[m[i]];
} else {
for (int i = x; i <= e[m[x]]; i++)
q += a[i] + add[m[i]];
for (int i = b[m[y]]; i <= y; i++)
q += a[i] + add[m[i]];
for (int i = m[x] + 1; i < m[y]; i++)
q += s[i] + add[i] * siz[i];
}
return q;
}