-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsegmentedTree.cpp
113 lines (71 loc) · 1.76 KB
/
segmentedTree.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
#include <iostream>
#include <vector>
using namespace std;
int log2(int n){
int answer = 0;
while(n > 0){
answer++;
n = n >> 1;
}
answer--;
return answer;
}
int power2(int p){
int base = 2;
int answer = 1;
while(p > 0){
if(p % 2){
answer*=base;
}
base*=base;
p = p >> 1;
}
return answer;
}
int getArraySize(const int &n){
return power2(log2(n)+2);
}
void initializeTree(int node, vector<int> &m , const vector<int> &n, int lim1, int lim2 ){
if(lim1 == lim2){
m[node] = lim1;
return;
}
initializeTree(2*node, m, n, lim1, (lim1+lim2)/2);
initializeTree(2*node + 1, m, n, (lim1+lim2)/2 + 1, lim2);
if(n[ m[2*node]] <= n[m[2*node+1]])
m[node] = m[2*node];
else
m[node] = m[2*node+1];
}
int query(int node, vector<int> m, vector<int> n, int lim1, int lim2, int q1, int q2){
int ans1, ans2;
if(q1 > lim2 || q2 < lim1) return -1;
if(q1<= lim1 && q2 >= lim2)
return m[node];
ans1 = query(node*2, m, n, lim1, (lim1 + lim2) /2 , q1, q2);
ans2 = query(2*node +1, m, n, (lim1 + lim2)/2 +1, lim2, q1, q2);
if(ans1 == -1)
return m[node] = ans2;
if(ans2 == -1)
return m[node] = ans1;
if(n[ans1] <= n[ans2])
return m[node] = ans1;
return m[node] = ans2;
}
int main(){
vector<int> n;
n.push_back(2);
n.push_back(4);
n.push_back(3);
n.push_back(1);
n.push_back(6);
n.push_back(7);
n.push_back(8);
n.push_back(9);
n.push_back(1);
n.push_back(7);
vector<int> m(getArraySize(n.size()),-1);
initializeTree(1, m, n, 0, n.size()-1);
cout << query(1, m, n, 0, n.size()-1, 0,1) << endl;
return 0;
}