@[Dry_ice](/user/214696) 修改后代码如下:
``` cpp
#include <stdio.h>
typedef long long LL;
const int N = 100005;
LL n, a[N], tr[4 * N], lazy[4 * N];
inline void pushup(LL id) {
tr[id] = tr[id << 1] + tr[id << 1 | 1];
}
inline void pushdown(LL id, LL l, LL r, LL mid) {
if (lazy[id]) {
lazy[id << 1] += lazy[id]; lazy[id << 1 | 1] += lazy[id];
tr[id << 1] += (mid - l + 1) * lazy[id]; tr[id << 1 | 1] += (r - mid) * lazy[id];
lazy[id] = 0;
}
}
inline void build(LL id, LL l, LL r) {
if (l == r) {tr[id] = a[l]; return;}
LL mid = (l + r) >> 1;
build(id << 1, l, mid);
build(id << 1 | 1, mid + 1, r);
pushup(id);
}
inline void update(LL id, LL l, LL r, LL x, LL y, LL v) {
if (x <= l && r <= y) {
lazy[id] += v;
tr[id] += (r - l + 1) * v;
return;
}
LL mid = (l + r) >> 1;
pushdown(id, l, r, mid);
if (x <= mid) {
update(id << 1, l, mid, x, y, v);
}
if (y > mid) {
update(id << 1 | 1, mid + 1, r, x, y, v);
}
pushup(id);
}
inline LL query(LL id, LL l, LL r, LL x, LL y) {
if (x <= l && r <= y) return tr[id];
LL mid = (l + r) >> 1, ans = 0;
pushdown(id, l, r, mid);
if (x <= mid) ans += query(id << 1, l, mid, x, y);
if (y > mid) ans += query(id << 1 | 1, mid + 1, r, x, y);
return ans;
}
int main(void) {
LL q;
scanf("%lld %lld", &n,&q);
for (LL i = 1; i <= n; ++i)
scanf("%lld", &a[i]);
build(1, 1, n);
for (; q--; ) {
LL opt, x, y, v;
scanf("%lld %lld %lld", &opt, &x, &y);
if (opt == 1) {
scanf("%lld", &v);
update(1, 1, n, x, y, v);
}
else
printf("%lld\n", query(1, 1, n, x, y));
}
return 0;
}
```
(应该没啥问题了)
by xtzic @ 2021-07-09 22:57:28
简要说一下错的几个点:
1. 区间加的系数要乘上区间长度。
2. `query` 里 `ans` 用于求和,初值为 $0$。
3. `scanf` 和 `printf` 对于 `long long` 要用 `%lld`。
4. 本题输入格式是先输入“该数列数字的个数和操作的总个数”,即代码中的 `n` 和 `q`。
by xtzic @ 2021-07-09 23:01:51
@[Dry_ice](/user/214696)
by xtzic @ 2021-07-09 23:02:17
@[xtzic](/user/485857) 蟹蟹qwq
by Dry_ice @ 2021-07-09 23:04:18