【模板】线段树 1 - 洛谷https://www.luogu.com.cn/problem/P3372
#include <iostream>
#include <cstdio>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <cstring>
#include <set>
#include <unordered_map>
#include <cmath>
#include <map>
#include <cctype>
#include <cstdlib>
#include <deque>
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
const int MN = 65005;
const int MAXN = 1000010;
const int INF = 0x3f3f3f3f;
#define IOS ios::sync_with_stdio(false)
#define lowbit(x) ((x)&(-x))
//线段树
ll tree[MAXN], mark[MAXN], s[MAXN];
int n, m;
void build(int p, int l, int r) {
if (l == r) {
tree[p] = s[l];
return;
}
int mid = l + r >> 1;
build(p << 1, l, mid);
build(p << 1 | 1, mid + 1, r);
tree[p] = tree[p << 1] + tree[p << 1 | 1];
}
inline void push_down(int p, int len) {
if (len <= 1)
return;
mark[p << 1] += mark[p];
mark[p << 1 | 1] += mark[p];
tree[p << 1] += mark[p] * (len - len / 2);
tree[p << 1 | 1] += mark[p] * (len / 2);
mark[p] = 0;
}
void update(int x, int y, ll d, int p, int l, int r) {
if (l >= x && r <= y) {
tree[p] += d * (r - l + 1), mark[p] += d;
return;
}
push_down(p, r - l + 1);
int mid = l + r >> 1;
if (mid >= x)
update(x, y, d, p << 1, l, mid);
if (mid < y)
update(x, y, d, p << 1 | 1, mid + 1, r);
tree[p] = tree[p << 1] + tree[p << 1 | 1];
}
ll query(int x, int y, int p, int l, int r) {
if (l >= x && r <= y)
return tree[p];
push_down(p, r - l + 1);
int mid = l + r >> 1;
ll ans = 0;
//printf("======\n");
if (mid >= x)
ans += query(x, y, p << 1, l, mid);
if (mid < y)
ans += query(x, y, p << 1 | 1, mid + 1, r);
//printf("%d\n", ans);
return ans;
}
int main() {
scanf("%d %d", &n, &m);
for (int i = 1; i <= n; i++) {
scanf("%lld", s + i);
}
build(1, 1, n);
int x, y;
ll k;
while (m--) {
int t;
scanf("%d", &t);
if (t == 1) {
scanf("%d%d%lld", &x, &y, &k);
update(x, y, k, 1, 1, n);
} else {
scanf("%d %d", &x, &y);
//printf("=====\n");
printf("%lld\n", query(x, y, 1, 1, n));
}
}
return 0;
}