P3372 【模板】线段树 1

1. 无懒标记


Update 2022-01-06:

草,今天来翻看我的老文章,突然发现我还写过一个无懒标记的线段树。就不删了,留个纪念。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include<cstdio>
#define int long long
const int MAXn = 1e5;

template <typename T>
inline void read(T &a) {
register char c;while (c = getchar(), (c < '0' || c > '9') && c != '-');register bool f = c == '-';register T x = f ? 0 : c - '0';while (c = getchar(), c >= '0' && c <= '9') {x = (x << 3) + (x << 1) + (c ^ 48);}a = f ? -x : x;
}
template <typename T, typename ...Argv>
inline void read(T &n, Argv &...argv) {
read(n), read(argv...);
}

#define ls (id << 1)
#define rs (id << 1 | 1)
int le[MAXn * 4 + 10], ri[MAXn * 4 + 10], sum[MAXn * 4 + 10];
inline void pushup(int id) {
sum[id] = sum[ls] + sum[rs];
}
void Build0(int id, int l, int r) {
le[id] = l;
ri[id] = r;
if (l == r) {
;
} else {
int mid = (l + r) >> 1;
Build0(ls, l, mid);
Build0(rs, mid + 1, r);
}
}
void BuildUseArr(int id, int l, int r, int *a) {
le[id] = l;
ri[id] = r;
if (l == r) {
sum[id] = a[l];
} else {
int mid = (l + r) >> 1;
BuildUseArr(ls, l, mid, a);
BuildUseArr(rs, mid + 1, r, a);
pushup(id);
}
}
void Add(int id, int l, int r, int k) {
if (le[id] == ri[id]) {
sum[id] = sum[id] + k;
} else {
int mid = (le[id] + ri[id]) >> 1;
if (l <= mid) Add(ls, l, r, k);
if (r > mid) Add(rs, l, r, k);
pushup(id);
}
}
int Eva(int id, int l, int r) {
if (le[id] >= l && ri[id] <= r) {
return sum[id];
} else {
int mid = (le[id] + ri[id]) >> 1, ans = 0;
if (l <= mid) ans = ans + Eva(ls, l, r);
if (r > mid) ans = ans + Eva(rs, l, r);
return ans;
}
}
#undef ls
#undef rs

int n, m, a[MAXn + 10];
signed main() {
read(n, m);
for (int i = 1; i <= n; ++i) {
read(a[i]);
}
BuildUseArr(1, 1, n, a);
for (int i = 1, opt, x, y, z; i <= m; ++i) {
read(opt);
switch (opt) {
case 1:
read(x, y, z);
Add(1, x, y, z);
break;
case 2:
read(x, y);
printf("%lld\n", Eva(1, x, y));
break;
}
}
}

2. 有懒标记

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int MAXn = 1e5;

template <typename T>
inline void read(T &a) {
register char c;while (c = getchar(), (c < '0' || c > '9') && c != '-');register bool f = c == '-';register T x = f ? 0 : c - '0';while (c = getchar(), c >= '0' && c <= '9') {x = (x << 3) + (x << 1) + (c ^ 48);}a = f ? -x : x;
}
template <typename T, typename ...Argv>
inline void read(T &n, Argv &...argv) {
read(n), read(argv...);
}

#define ls (id << 1)
#define rs (id << 1 | 1)
int le[MAXn * 4 + 10], ri[MAXn * 4 + 10], add[MAXn * 4 + 10], sum[MAXn * 4 + 10];
inline void pushup(int id) {
sum[id] = sum[ls] + sum[rs];
}
inline void pushdown(int id) {
sum[ls] = sum[ls] + add[id] * (ri[ls] - le[ls] + 1);
sum[rs] = sum[rs] + add[id] * (ri[rs] - le[rs] + 1);
add[ls] = add[ls] + add[id];
add[rs] = add[rs] + add[id];
add[id] = 0;
}
void Build0(int id, int l, int r) {
le[id] = l;
ri[id] = r;
if (l == r) {
;
} else {
int mid = (l + r) >> 1;
Build0(ls, l, mid);
Build0(rs, mid + 1, r);
}
}
void BuildUseArr(int id, int l, int r, int *a) {
le[id] = l;
ri[id] = r;
if (l == r) {
sum[id] = a[l];
} else {
int mid = (l + r) >> 1;
BuildUseArr(ls, l, mid, a);
BuildUseArr(rs, mid + 1, r, a);
pushup(id);
}
}
void Add(int id, int l, int r, int k) {
if (le[id] >= l && ri[id] <= r) {
sum[id] = sum[id] + k * (ri[id] - le[id] + 1);
add[id] = add[id] + k;
} else {
pushdown(id);
int mid = (le[id] + ri[id]) >> 1;
if (l <= mid) Add(ls, l, r, k);
if (r > mid) Add(rs, l, r, k);
pushup(id);
}
}
int Eva(int id, int l, int r) {
if (le[id] >= l && ri[id] <= r) {
return sum[id];
} else {
pushdown(id);
int mid = (le[id] + ri[id]) >> 1, ans = 0;
if (l <= mid) ans = ans + Eva(ls, l, r);
if (r > mid) ans = ans + Eva(rs, l, r);
return ans;
}
}
#undef ls
#undef rs

int n, m, a[MAXn + 10];
signed main() {
read(n, m);
for (int i = 1; i <= n; ++i) {
read(a[i]);
}
BuildUseArr(1, 1, n, a);
for (int i = 1, opt, x, y, z; i <= m; ++i) {
read(opt);
switch (opt) {
case 1:
read(x, y, z);
Add(1, x, y, z);
break;
case 2:
read(x, y);
printf("%lld\n", Eva(1, x, y));
break;
}
}
}