-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathSegment Tree.java
More file actions
140 lines (93 loc) · 3.14 KB
/
Segment Tree.java
File metadata and controls
140 lines (93 loc) · 3.14 KB
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
import java.util.*;
import java.lang.*;
import java.io.*;
import java.math.*;
class Ideone{
//segment tree
public static Scanner scn = new Scanner(System.in);
public static class SegmentTree{
private int[] tree;
public void print(){
if(tree.length == 0)
return;
for(int data : tree)
System.out.print("" + data + " ");
System.out.println();
}
public void build(int[] A){
int x = (int) (Math.ceil(Math.log(A.length) / Math.log(2)));
//Maximum size of segment tree
int max_size = 2 * (int) Math.pow(2, x) - 1;
//instantiate tree array
this.tree = new int[max_size];
build(1, 0, A.length - 1, A);
}
private int build(int node, int start, int end, int[] A){
if(start == end){
// Leaf node will have a single element
this.tree[node] = A[start];
return tree[node];
}
int mid = (start + end) >> 1;
int left = build(2*node, start, mid, A);
int right = build(2*node+1, mid+1, end, A);
this.tree[node] = Math.max(left , right);
return this.tree[node];
}
private int query(int ss, int se, int qs, int qe, int index){
// If segment of this node is a part of given range, then return the min of the segment
if (qs <= ss && qe >= se)
return tree[index];
// If segment of this node is outside the given range
if (se < qs || ss > qe)
return Integer.MIN_VALUE;
// If a part of this segment overlaps with the given range
int mid = (ss + se) >> 1;
return Math.max(query(ss, mid, qs, qe, 2 * index),
query(mid + 1, se, qs, qe, 2 * index + 1));
}
// Return minimum of elements in range from index qs (quey start) to qe (query end).
public int query(int qs, int qe, int[] A){
int n = A.length;
// Check for erroneous input values
if (qs < 0 || qe > n - 1 || qs > qe) {
System.out.println("Invalid Input");
return -1;
}
return query(0, n - 1, qs, qe, 1);
}
public void update(int idx, int val, int[] A){
update(1, 0, A.length - 1, idx, val, A);
}
private int update(int node, int start, int end, int idx, int val, int[] A){
if(start == end){
// Leaf node
A[idx] = val;
this.tree[node] = val;
return val;
}
int mid = (start + end) >> 1;
if(start <= idx && idx <= mid){
// If idx is in the left child, recurse on the left child
int left = update(2*node, start, mid, idx, val, A);
int right = this.tree[2*node+1];
this.tree[node] = Math.max(left, right);
} else {
// if idx is in the right child, recurse on the right child
int left = this.tree[2*node];
int right = update(2*node+1, mid+1, end, idx, val, A);
this.tree[node] = Math.max(left, right);
}
return this.tree[node];
}
}
public static void main (String[] args) throws java.lang.Exception{
SegmentTree st = new SegmentTree();
int[] arr = {17, 18, 5, 2, 7, 11, 1, 13, 9, 16};
st.build(arr);
st.print();
System.out.println("" + st.query(1, 5, arr));
st.update(4, 20, arr);
System.out.println("" + st.query(1, 5, arr));
}
}