-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSegmentTree.java
More file actions
91 lines (79 loc) · 2.02 KB
/
SegmentTree.java
File metadata and controls
91 lines (79 loc) · 2.02 KB
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
public class SegmentTree {
int n, a[];
long[] sum, lazy;
SegmentTree(int[] a) {
this(a.length);
this.a = a;
build(1, 0, n - 1);
}
SegmentTree(int n) {
this.n = n;
sum = new long[4 * n];
lazy = new long[4 * n];
}
void build(int node, int tl, int tr) {
if (tl == tr)
sum[node] = a[tl];
else {
int mid = (tl + tr) / 2, left = node * 2, right = left + 1;
build(left, tl, mid);
build(right, mid + 1, tr);
merge(node);
}
}
void updatePoint(int idx, int v) { // a[idx]+=v
updatePoint(1, 0, n - 1, idx, v);
}
void updatePoint(int node, int tl, int tr, int idx, int v) {
if (tl == tr)
sum[node] += v;
else {
int mid = (tl + tr) / 2, left = node * 2, right = left + 1;
if (idx <= mid)
updatePoint(left, tl, mid, idx, v);
else
updatePoint(right, mid + 1, tr, idx, v);
merge(node);
}
}
long query(int l, int r) {
return query(1, 0, n - 1, l, r);
}
long query(int node, int tl, int tr, int l, int r) {
if (tr < l || r < tl)
return 0;
if (tl >= l && tr <= r)
return sum[node];
int mid = (tl + tr) / 2, left = node * 2, right = left + 1;
propagate(node, tl, tr);
return query(left, tl, mid, l, r) + query(right, mid + 1, tr, l, r);
}
void merge(int node) {
sum[node] = sum[2 * node] + sum[2 * node + 1];
}
void updateRange(int l, int r, int v) {
updateRange(1, 0, n - 1, l, r, v);
}
void updateRange(int node, int tl, int tr, int l, int r, int v) {
if (tr < l || r < tl)
return;
if (tl >= l && tr <= r) {
sum[node] += (tr - tl + 1) * 1L * v;
lazy[node] += v;
return;
}
int mid = (tl + tr) / 2, left = node * 2, right = left + 1;
propagate(node, tl, tr);
updateRange(left, tl, mid, l, r, v);
updateRange(right, mid + 1, tr, l, r, v);
merge(node);
}
private void propagate(int node, int tl, int tr) {
int mid = (tl + tr) / 2, left = node * 2, right = left + 1;
sum[left] += (mid - tl + 1) * 1L * lazy[node];
lazy[left] += lazy[node];
sum[right] += (tr - mid) * 1L * lazy[node];
lazy[right] += lazy[node];
lazy[node] = 0;
}
}