7
7
package com .williamfiset .algorithms .datastructures .segmenttree ;
8
8
9
9
public class CompactSegmentTree {
10
+
11
+ // Observation:
12
+ // The ST doesn't lend itself to being traverse top down easily,
13
+ // rather, bottom up is nicer in this compact representation.
14
+
15
+ // Two implementations:
16
+ // 1) top down
17
+ // 2) bottom up
18
+
19
+ // public class Pair {
20
+ // // Index of the value in the original which derived the best value. The index doesn't
21
+ // // always make sense depending on the query type. for example the index makes sense for RMQ
22
+ // // but not for sum queries which aggregate values.
23
+ // int index;
24
+
25
+ // // The best value in the range.
26
+ // long value;
27
+ // public Pair(int index, long value) {
28
+ // this.index = index;
29
+ // this.value = value;
30
+ // }
31
+ // public String toString() {
32
+ // return "(index = " + index + ", " + value + ")";
33
+ // }
34
+ // }
35
+
36
+ // // The number of elements in the original values array.
37
+ // private int N;
38
+
39
+ // // Let UNIQUE be a value which does NOT and will NOT appear in the segment tree.
40
+ // // This value is used as a replacement for null to avoid unboxing values.
41
+ // //
42
+ // // TODO(william): should probably replace the tree with Long[] instead of long[] to remove this...
43
+ // private long UNIQUE = 8123572096793136074L;
44
+
45
+ // // Segment tree range values. This array is 1 based so the first entry tree[0]
46
+ // // is unused.
47
+ // private long[] tree;
48
+
49
+ // public CompactSegmentTree(int size) {
50
+ // tree = new long[2 * (N = size)];
51
+ // java.util.Arrays.fill(tree, UNIQUE);
52
+ // }
53
+
54
+ // public CompactSegmentTree(long[] values) {
55
+ // this(values.length);
56
+ // for (int i = 0; i < N; i++) modify(i, values[i]);
57
+ // }
58
+
59
+ // // This is the segment tree function we are using for queries.
60
+ // // The function must be an associative function, meaning
61
+ // // the following property must hold: f(f(a,b),c) = f(a,f(b,c)).
62
+ // // Common associative functions used with segment trees
63
+ // // include: min, max, sum, product, GCD, and etc...
64
+ // private int function(int ai, int bi) {
65
+ // if (ai == -1 || tree[ai] == UNIQUE) return bi;
66
+ // else if (bi == -1 || tree[bi] == UNIQUE) return ai;
67
+
68
+ // // return a + b; // sum over a range
69
+ // // return (a > b) ? a : b; // maximum value over a range
70
+ // if (tree[ai] < tree[bi]) { // minimum value over a range
71
+ // return ai;
72
+ // } else {
73
+ // return bi;
74
+ // }
75
+ // // return a * b; // product over a range (watch out for overflow!)
76
+ // }
77
+
78
+ // // Adjust point i by a value, O(log(n))
79
+ // public void modify(int i, long value) {
80
+ // // Setting tree[0] to the value and then using the function is a
81
+ // // small hack to see if updating the value makes an improvement.
82
+ // tree[0] = value;
83
+ // if (function(i + N, 0) == 0) {
84
+ // tree[i + N] = value;
85
+ // }
86
+ // // tree[i + N] = function(tree[i + N], value);
87
+ // for (i += N; i > 1; i >>= 1) {
88
+ // tree[i >> 1] = tree[function(i, i ^ 1)];
89
+ // }
90
+ // }
91
+
92
+ // // Query interval [l, r), O(log(n))
93
+ // public Pair query(int l, int r) {
94
+ // long res = UNIQUE;
95
+ // int resIndex = -1;
96
+
97
+ // for (l += N, r += N; l < r; l >>= 1, r >>= 1) {
98
+ // int bestLeft = -1, bestRight = -1;
99
+ // if ((l & 1) != 0) {
100
+ // bestLeft = function(resIndex, l++);
101
+ // }
102
+ // if ((r & 1) != 0) {
103
+ // bestRight = function(resIndex, --r);
104
+ // }
105
+ // resIndex = Math.min(bestLeft, bestRight);
106
+ // }
107
+ // if (tree[resIndex] == UNIQUE) {
108
+ // throw new IllegalStateException("UNIQUE should not be the return value.");
109
+ // }
110
+ // // TODO(william): I don't think the result index is returning what you think it is returning.
111
+ // // Not convinced the leaf node indexes get propagated at all...
112
+ // // TODO(william): What about multiple matches, what then?
113
+ // return new Pair(resIndex, tree[resIndex]);
114
+ // }
115
+
10
116
private int N ;
11
117
12
118
// Let UNIQUE be a value which does NOT
@@ -23,6 +129,7 @@ public CompactSegmentTree(int size) {
23
129
24
130
public CompactSegmentTree (long [] values ) {
25
131
this (values .length );
132
+ // TODO(william): Implement smarter construction.
26
133
for (int i = 0 ; i < N ; i ++) modify (i , values [i ]);
27
134
}
28
135
@@ -61,4 +168,10 @@ public long query(int l, int r) {
61
168
}
62
169
return res ;
63
170
}
171
+
172
+ public static void main (String [] args ) {
173
+ long [] values = new long []{3 ,0 ,8 ,9 ,8 ,2 ,5 ,3 ,7 ,1 };
174
+ CompactSegmentTree st = new CompactSegmentTree (values );
175
+ System .out .println (java .util .Arrays .toString (st .tree ));
176
+ }
64
177
}
0 commit comments