1
+ // Problem:
2
+ // We have an array a[0...n-1]. We should be able to efficiently
3
+ // find the minimum value from index qs(query start) to qe(query end)
4
+ // where 0 <= qs <= qe <= n-1.
5
+ // Also write code for efficient updates on an element
6
+ // or a range of element
7
+
8
+ #include < iostream>
9
+ #include < climits>
10
+ using namespace std ;
11
+
12
+ void buildTree (int * a, int s, int e, int * tree, int index){
13
+ // base case
14
+ if (s == e){
15
+ tree[index] = a[s];
16
+ return ;
17
+ }
18
+
19
+ // recursive case
20
+ int mid = (s+e)/2 ;
21
+ buildTree (a, s, mid, tree, 2 *index);
22
+ buildTree (a, mid+1 , e, tree, 2 *index+1 );
23
+ tree[index] = min (tree[2 *index], tree[2 *index+1 ]);
24
+ return ;
25
+ }
26
+
27
+ int query (int * tree, int ss, int se, int qs, int qe, int index){
28
+ // complete overlap
29
+ if (ss>=qs && se<=qe)
30
+ return tree[index];
31
+
32
+ // no overlap
33
+ if (ss>qe || se<qs)
34
+ return INT_MAX;
35
+
36
+ // partial overlap
37
+ int mid = (ss+se)/2 ;
38
+ int leftMin = query (tree, ss, mid, qs, qe, 2 *index);
39
+ int rightMin = query (tree, mid+1 , se, qs, qe, 2 *index+1 );
40
+ return min (leftMin, rightMin);
41
+ }
42
+
43
+ // updating single index
44
+ void updateIndex (int * tree, int ss, int se, int i, int incr, int index){
45
+ // out of bounds range
46
+ if (i>se || i<ss){
47
+ return ;
48
+ }
49
+
50
+ // leaf node
51
+ if (ss == se){
52
+ tree[index] = tree[index] + incr;
53
+ return ;
54
+ }
55
+
56
+ // partial overlap - call left and right child
57
+ int mid = (ss+se)/2 ;
58
+ updateIndex (tree, ss, mid, i, incr, 2 *index);
59
+ updateIndex (tree, mid+1 , se, i, incr, 2 *index+1 );
60
+ tree[index] = min (tree[2 *index], tree[2 *index+1 ]);
61
+ return ;
62
+ }
63
+
64
+ // updating range of indices
65
+ int updateRange (int * tree, int ss, int se, int l, int r, int incr, int index){
66
+ // out of bounds
67
+ if (l > se || r < ss)
68
+ return ;
69
+
70
+ // leaf node
71
+ if (ss == se){
72
+ tree[index] += incr;
73
+ return ;
74
+ }
75
+
76
+ // partial overlap - call left and right child
77
+ int mid = (ss+se)/2 ;
78
+ updateRange (tree, ss, mid, l, r, incr, 2 *index);
79
+ updateRange (tree, mid+1 , se, l, r, 2 *indx+1 );
80
+ tree[index] = min (tree[2 *index], tree[2 *index+1 ]);
81
+ return ;
82
+ }
83
+
84
+
85
+ int main (){
86
+ int n;
87
+ // cin>>n;
88
+ int a[] = {1 , 3 , 2 , -5 , 6 , 4 };
89
+ n = sizeof (a)/sizeof (int );
90
+ // for(int i = 0 ; i < n ; i++)
91
+ // cin>>a[i];
92
+
93
+ int * tree = new int [4 *n+1 ];
94
+ buildTree (a, 0 , n-1 , tree, 1 );
95
+
96
+ // print tree
97
+ for (int i = 1 ; i<=4 *n; i++){
98
+ cout<<tree[i]<<" " ;
99
+ }
100
+ cout<<endl;
101
+
102
+ // query
103
+ int l=2 , r=5 ;
104
+ // cin>>l>>r;
105
+ cout<<query (tree, 0 , n-1 , l, r, 1 );
106
+
107
+ // update index
108
+ updateIndex (tree, 0 , n-1 , 4 , -3 , 1 );
109
+
110
+ // print tree
111
+ for (int i = 1 ; i<=4 *n; i++){
112
+ cout<<tree[i]<<" " ;
113
+ }
114
+ cout<<endl;
115
+ return 0 ;
116
+ }
0 commit comments