-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSegment_Tree.cpp
124 lines (114 loc) · 3.43 KB
/
Segment_Tree.cpp
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include <bits/stdc++.h>
using namespace std;
class SegmentTree
{
vector<int> seg;
vector<int> lazy;
public:
SegmentTree(int n)
{
seg.resize(4 * n + 1);
lazy.resize(4 * n + 1);
}
void build(int ind, int low, int high, int a[])
{
if (low == high)
{
seg[ind] = a[low];
return;
}
int mid = (low + high) / 2;
build(2 * ind + 1, low, mid, a);
build(2 * ind + 2, mid + 1, high, a);
seg[ind] = min(seg[2 * ind + 1], seg[2 * ind + 2]);
}
int query(int ind, int low, int high, int l, int r)
{
// no overlap
if (r < low || l > high)
return INT_MAX;
// complete overlap
if (l <= low && r >= high)
return seg[ind];
int mid = (low + high) / 2;
int left = query(2 * ind + 1, low, mid, l, r);
int right = query(2 * ind + 2, mid + 1, high, l, r);
return min(left, right);
}
void pointUpdate(int ind, int low, int high, int i, int val)
{
// here i is the index of the element to be updated
if (low == high)
{
seg[ind] = val;
return;
}
int mid = (low + high) / 2;
if (i <= mid)
pointUpdate(2 * ind + 1, low, mid, i, val);
else
pointUpdate(2 * ind + 2, mid + 1, high, i, val);
seg[ind] = min(seg[2 * ind + 1], seg[2 * ind + 2]);
}
// l, r -> update the range value
// this is for the sum of range
void rangeUpdate(int ind, int low, int high, int l, int r, int val)
{
if (lazy[ind] != 0)
{
seg[ind] += (high - low + 1)*lazy[ind];
if (low != high) // not a leaf node
{
lazy[2 * ind + 1] += lazy[ind]; // propogation the lazy value to the children
lazy[2 * ind + 2] += lazy[ind];
}
lazy[ind] = 0; // reset the lazy value as it has been propogated
}
if (r <low || l > high || low > high) return;
if (low >= l && high <= r)
{
seg[ind] += (high - low + 1)*val;
if (low != high)
{
lazy[2 * ind + 2] += lazy[ind];
lazy[2 * ind + 1] += lazy[ind];
}
return;
}
int mid = (low + high) >> 1;
rangeUpdate(2 * ind + 1, low, mid, l, r, val);
rangeUpdate(2 * ind + 2, mid + 1, high, l, r, val);
seg[ind] = seg[2 * ind + 1] + seg[2 * ind + 2];
}
int querySumLazy(int ind, int low, int high, int l, int r, int val)
{
if (lazy[ind] != 0)
{
seg[ind] += (high - low + 1)*lazy[ind];
if (low != high) // not a leaf node
{
lazy[2 * ind + 1] += lazy[ind]; // propogation the lazy value to the children
lazy[2 * ind + 2] += lazy[ind];
}
lazy[ind] = 0; // reset the lazy value as it has been propogated
}
if (r <low || l > high || low > high) return 0;
if (low >= l && high <= r)
{
return seg[ind];
}
int mid = (low + high) >> 1;
int left = querySumLazy(2 * ind + 1, low, mid, l, r, val);
int right = querySumLazy(2 * ind + 2, mid + 1, high, l, r, val);
return left + right;
}
};
int main()
{
int n;
cin >> n;
int a[n];
int seg[4 * n];
for (int i = 0; i < n; i++)
cin >> a[i];
}