-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathSegment_Trees.cpp
53 lines (53 loc) · 2.65 KB
/
Segment_Trees.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
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
//Segment Tree is a data structure that allows range query and update operations in O(LogN) time
//The entire structure takes O(N) time and space to build
//Range Updates are difficult to do efficiently, the require an algorithm called Lazy Propagation
int MidPoint(int LowerBound, int UpperBound){
return (LowerBound+UpperBound)/2;
}
int LeftChild(int Index){
return Index*2 + 1;
}
int RightChild(int Index){
reIndex*2 + 2;
}
int MergeOperation(int Value1, int Value2){
return min(Value1, Value2);
}
int IdentityElement(){
return 1e9;
}
void BuildTree(int LowerBound, int UpperBound, int Index, int SegmentTree[], int OriginalArray[]){
if(LowerBound==UpperBound) SegmentTree[Index] = OriginalArray[LowerBound];
else{
BuildTree(LowerBound, MidPoint(LowerBound, UpperBound), LeftChild(Index), SegmentTree, OriginalArray);
BuildTree(MidPoint(LowerBound, UpperBound)+1, UpperBound, RightChild(Index), SegmentTree, OriginalArray);
SegmentTree[Index] = MergeOperation(SegmentTree[LeftChild(Index)], SegmentTree[RightChild(Index)]);
}
}
int Query(int LowerBound, int UpperBound, int Index, int QueryLowerBound, int QueryUpperBound, int SegmentTree[]){
if(LowerBound>=QueryLowerBound && UpperBound<=QueryUpperBound) return SegmentTree[Index];
if(LowerBound>QueryUpperBound || UpperBound<QueryLowerBound) return IdentityElement();
return MergeOperation(Query(LowerBound, MidPoint(LowerBound, UpperBound), LeftChild(Index), QueryLowerBound, QueryUpperBound, SegmentTree), Query(MidPoint(LowerBound, UpperBound)+1, UpperBound, RightChild(Index), QueryLowerBound, QueryUpperBound, SegmentTree));
}
void Update(int LowerBound, int UpperBound, int Index, int UpdateIndex, int UpdateValue, int SegmentTree[]){
if(LowerBound==UpperBound && UpperBound==UpdateIndex){
SegmentTree[UpdateIndex] = UpdateValue;
}
if(LowerBound>UpdateIndex || UpperBound<UpdateIndex) return;
Update(LowerBound, MidPoint(LowerBound, UpperBound), LeftChild(Index), UpdateIndex, UpdateValue, SegmentTree);
Update(MidPoint(LowerBound, UpperBound)+1, UpperBound, RightChild(Index), UpdateIndex, UpdateValue, SegmentTree);
SegmentTree[Index] = MergeOperation(SegmentTree[LeftChild(Index)], SegmentTree[RightChild(Index)]);
}
int main(){
int NumberOfElements;
cin>>NumberOfElements;
int OriginalArray[NumberOfElements];
for(int i = 0;i<NumberOfElements;i++) cin>>OriginalArray[i];
int LengthOfSegmentTree = pow(2, ceil(log2(NumberOfElements)))*2 - 1;
int SegmentTree[LengthOfSegmentTree];
BuildTree(1, NumberOfElements, 0, SegmentTree, OriginalArray);
}