-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathSegmentTree.cpp
158 lines (137 loc) · 4.06 KB
/
SegmentTree.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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
// Node structure
struct Node{
ll max=0; // Change according to function
ll min=1e9+7;
ll sum=0;
Node(ll mx, ll mn, ll sm): max(mx), min(mn), sum(sm){}
Node(ll x): max(x), min(x), sum(x){}
Node(): max(0), min(1e9+7), sum(0){}
};
struct ST{
ll N;
vector<Node> st, lazy;
vector<bool> clazy;
Node ret;
ST(ll n): N(n), st(4*n+10),lazy(4*n+10),clazy(4*n+10,false){}
//Assignment
void assign(ll n){
N=n;
st.resize(4*n+10);
lazy.resize(4*n+10);
clazy.assign(4*n+10,false);
ret.max=0; // Change according to function
ret.min=1e9+7;
ret.sum=0;
}
// All merging functions
void merge(Node &cur, Node &l, Node &r){
cur.max = max(l.max , r.max); // Change according to function
cur.min = min(l.min , r.min);
cur.sum = l.sum + r.sum;
}
void assignNode(ll node, ll val){
st[node].max = val;
st[node].min = val;
st[node].sum = val;
}
void assignLazy(ll node, ll val){
lazy[node].max = val; // Change according to function
lazy[node].min = val;
lazy[node].sum = val;
}
//Propogation in lazy-update
void propogate(ll node, ll l, ll r){
if(!clazy[node]) return;
clazy[node]=false;
st[node].max = lazy[node].max; // Change according to function
st[node].min = lazy[node].min;
st[node].sum += (r-l)*lazy[node].sum;
if(r-l>=2){
clazy[2*node]=true;
clazy[2*node+1]=true;
lazy[2*node].max = lazy[node].max;
lazy[2*node+1].max = lazy[node].max; // Change according to function
lazy[2*node].min = lazy[node].min;
lazy[2*node+1].min = lazy[node].min;
lazy[2*node].sum += lazy[node].sum;
lazy[2*node+1].sum += lazy[node].sum;
}
lazy[node] = ret;
}
void build(ll node, ll l , ll r, vll & a){
if(r-l<2){
assignNode(node,a[l]);
return;
}
ll mid = (l+r)/2;
build(2*node,l,mid,a);
build(2*node+1,mid,r,a);
merge(st[node], st[2*node], st[2*node+1]);
}
void build(ll node, ll l, ll r){
st[node]=ret;
if(r-l<2){
return;
}
ll mid = (l+r)/2;
build(2*node,l,mid);
build(2*node+1,mid,r);
}
Node Query(ll node, ll l, ll r, ll x, ll y){
propogate(node,l,r);
if(x>=r or y<=l) return ret; // Change according to function
if(x<=l and y>=r) return st[node];
ll mid = (l+r)/2;
Node L = Query(2*node,l,mid,x,y);
Node R = Query(2*node+1,mid,r,x,y);
Node C;
merge(C,L,R);
return C;
}
Node pQuery(ll node, ll l, ll r, ll pos){
propogate(node,l,r);
if(r-l<2) return st[node];
ll mid = (l+r)/2;
if(pos<mid) return pQuery(2*node,l,mid,pos);
else return pQuery(2*node+1,mid,r,pos);
}
void Update(ll node, ll l, ll r, ll x, ll y, ll val){
propogate(node,l,r);
if(x>=r or y<=l) return;
if(x<=l and y>=r){
clazy[node]=1;
assignLazy(node,val);
propogate(node,l,r);
return;
}
ll mid = (l+r)/2;
Update(2*node,l,mid,x,y,val);
Update(2*node+1,mid,r,x,y,val);
merge(st[node], st[2*node], st[2*node+1]);
}
void pUpdate(ll node, ll l, ll r, ll pos, ll val){
propogate(node,l,r);
if(r-l<2){
assignNode(node,val);
return;
}
ll mid = (l+r)/2;
if(pos<mid) pUpdate(2*node,l,mid,pos,val);
else pUpdate(2*node+1,mid,r,pos,val);
merge(st[node],st[2*node],st[2*node+1]);
}
Node query(ll pos){
return pQuery(1, 0, N, pos);
}
Node query(ll L, ll R){
if(L>=R) return ret;
return Query(1, 0, N, L, R);
}
void update(ll pos, ll val){
return pUpdate(1, 0, N, pos, val);
}
void update(ll L, ll R, ll val){
if(L>=R) return ;
return Update(1, 0, N, L, R, val);
}
};